April 2002 Draft
JavaScript 2.0

Monday, April 22, 2002

JavaScript 2.0 is an experimental proposal maintained by waldemar for future changes in the JavaScript language. The eventual language may differ significantly from this proposal, but the goal is to move in the directions indicated here and do so via a coordinated plan rather than adding miscellaneous features ad hoc on a release-by-release basis.

JavaScript is Netscape’s implementation of the ECMAScript standard. The development of JavaScript 2.0 is heavily coordinated with the ECMA TC39TG1 working group. JavaScript closely matches the ECMAScript Edition 4 standard under development. The intent is to make JavaScript 2.0 and ECMAScript Edition 4 be the same language, but JavaScript 2.0 will also include a few features for which more feedback and experience is appropriate before standardizing them.

This document describes the JavaScript 2.0 language. Information that is not part of Netscape’s ECMAScript Edition 4 proposal is highlighted with a yellow background.



The following are recent major changes in this document:

Date Revisions
Apr 22, 2002
  • Corrected and clarified the rules for when a variable or a constant may be accessed. Except for type- and attribute-less definitions, constants and variables are accessible only after being defined. Constants may be written at most once. Type expressions must be compile-time constant expressions.
  • A constant and a setter with the same qualified name may not be defined in the same scope.
  • Hoisting does not occur into class scope (this possibility is now excluded by the definition of a regional scope).
  • explicit is now an attribute instead of a specialized namespace.
  • Corrected the interaction of overriding and namespace defaulting in a definition. Defined the namespace defaulting and overriding rules.
  • Replaced mayOverride by override(undefined). Added regular rules for the behavior of overriding and the override attribute.
  • Allowed uninitialized semantic record fields.
  • Continuing to write the formal semantics. Added semantics for constant and variable declarations.
Mar 4, 2002
  • Restricted pragma arguments to be literal booleans, numbers, or strings. Also, strict mode changes now affect the semicolon after the pragma.
  • Removed class declarations without a body.
  • Removed include/exclude clauses from use directives. These now apply only to import directives and now indicate which top-level properties are shared. Simplified the name lookup algorithms to not account for includes/excludes on individual use directives.
  • Made other minor grammar changes to share productions and their semantics without affecting the language.
  • Added for each to the list of computation steps.
  • Added abbreviated notation for copying most of the fields from an existing tuple or record into a newly constructed one.
  • Continuing to write the formal semantics. Made major changes and additions to the formal semantics for evaluation of expressions and statements. Reorganized object layout and unified frames with container objects. Defined package objects. Added a phase parameter to distinguish compile-time constant expressions from runtime expressions.
Jan 4, 2002
  • Removed attributes from pragmas. Although somewhat useful, this made parsing dependent on attribute evaluation, and I'd rather not have such a dependency in the language.
Dec 20, 2001
  • Regularized the grammar of statements and directives. Separated annotated blocks into groups of either directives or substatements, which eliminated the troublesome situation of a definition being located in a substatement that happens to be a group. The attributes on a group of substatements are now restricted to only true and false.
Dec 19, 2001
  • Removed the local attribute, which was no longer necessary for anything.
  • Added the compile attribute to explicitly mark which const definitions must be compile-time constants. This became necessary because the semantics of compile-time const definitions are subtly different from those of regular const definitions, and it became unwieldy to try to guess which one a const definition is, based on how it is used.
  • Revamped the description of compile-time constant expressions. Removed the references to dominators. There are now two kinds of compile-time constant expressions: ones that allow forward references and ones that don’t.
Dec 17, 2001
  • Disallowed nested labels with the same name in the same function in the semantics.
  • Renamed GoContinue to Continue, GoBreak to Break, GoThrow to ThrownValue, and GoReturn to ReturnedValue in the semantics.
  • Pragmas may now take attributes (true and false only).
  • Fixed outdated text in the description of function parameters.
Dec 6, 2001
  • Reverted to the old definition of the Integer type; it’s back to being the set of integral IEEE doubles.
  • Deleted the double type and made Number act as double once again.
  • Renamed Character to char.
  • Rewrote the machine types section once again. Renamed int8, uint8, int16, uint16, int32, uint32, int64, and uint64 to sbyte, byte, short, ushort, int, uint, long, and ulong respectively. The first six of these are now subtypes of Integer; long and ulong are now disjoint from Number.
  • Renamed “coercion” to “implicit coercion” and “cast” to “explicit coercion”.
  • Added special case to the is operator to treat –0.0 as though it were +0.0.
  • Made the as operator support implicit coercions.
  • Added implicit coercions to the concept of a type.
Nov 26, 2001
  • Added support for comments inside functions in the semantics. Removed invariant and steps and turned them into comments.
  • Temporary variables in the semantics can now be declared without assigning a value to them.
  • Added more syntactic semantics.
  • Removed the #, ->, .., and @ tokens.
  • Made the Character type distinct from the set of single-character Strings.
  • Made double be a subtype of Number, which is now the union of numeric types. Made Integer distinct from double and accept unlimited-precision integers. Unified the integral machine types with Integer.
  • Made integral conversions that can result in loss of range error-checked by default. Added the wrap pragma to convert the behavior to wraparound.
Oct 26, 2001
Oct 18, 2001
Oct 16, 2001
Oct 3, 2001
  • Updated semantic notation to combine action procedures for multiple expansions of a nonterminal into one action procedure. Also deleted the notation for simple procedures to reduce confusion.
  • Reformatted the formal semantics and incorporated the above notation changes.
  • Added indexes to the rtf files.
Sep 26, 2001
  • Added more semantics.
  • delete now takes a PostfixExpression instead of a PostfixExpressionOrSuper.
Sep 24, 2001
Aug 22, 2001
Aug 17, 2001
Aug 15, 2001
Aug 10, 2001
Jul 24, 2001
  • Removed the +t type constructor. It’s now in the rationale.
  • null is now a valid String value, distinct from the empty string.
  • Removed the const Array and const t types. Added the StaticArray[t], DynamicArray[t], ConstArray, and ConstArray[t] types.
  • Removed the t[] notation. This is now reserved for fixed-size machine array types.
  • Removed the const operator.
  • Instance member initializers are re-evaluated each time a new instance is created.
  • Toughened the rules for argument type matching in overrides.
  • Changed the variable lookup rules to make a class’s instance members visible but inaccessible in static methods.
  • Removed the empty argument list case from the PragmaExpr and UseDirective grammars.
  • Removed the * wildcard case from IncludesExcludes.
  • Regularized the ImportDirective grammar.
  • Enabled true and false attributes on use namespace directives. Restricted import directive attributes to only true and false.
  • Simplified various grammar productions and renamed grammar nonterminals without affecting the language. Folded the Definition production into the Directive productions.
  • Specified extent of pragmas.
Jun 29, 2001
  • Renamed instanceof to is to allow it to have the new, more sensible semantics without breaking JavaScript 1.5 programs. instanceof is not part of JavaScript 2.0 but can be supported for legacy programs. is is a new reserved word.
  • Removed the [no line break] constraints after use.
  • Updated the compatibility section.
Jun 15, 2001
  • Renamed the machine types byte, ubyte, short, ushort, int, uint, long, ulong to int8, uint8, int16, uint16, int32, uint32, int64, and uint64 respectively.
  • Renamed Tuple to const Array.
  • Removed the nonindexable and nonenumerable visibility modifier attributes. Updated the definitions of the indexable and enumerable attributes.
  • Removed the indexable attribute keyword, but the indexable concept still exists because it is needed for compatibility with JavaScript 1.5.
  • Changed the default for public definitions to nonindexable and non-enumerable.
  • Forbade conflicting or repeated attributes.
  • The default member modifier attribute for const definitions is now final instead of static.
  • Removed the requirement to use this. to initialize instance constants from a constructor.
  • Setters can no longer return a value; the result of an assignment expression is now always the value of its right side.
  • Only classes with at least one member with the prototype attribute will themselves have a predefined prototype global member.
  • Renamed language directives to pragmas and removed the list of JavaScript versions.
  • Simplified the syntax of pragmas and changed the syntax of pragmas, namespace uses, and imports to make them consistent. Eliminated noninsertable semicolons.
  • A parenthesized expression FieldName is now a JavaScript extension.
  • Noted that an implementation does not have to support package circularities but may do so as an extension.
  • Interchanged the names of the Definition and AnnotatedDefinition nonterminals.
  • Renamed the parser grammar to the syntactic grammar and the lexer grammar to the lexical grammar for consistency with ECMAScript Edition 3.
Apr 11, 2001
  • Replaced the @ operator by the as operator, which is now a new reserved word and has a lower precedence to match instanceof. The as operator now returns null if the type doesn’t match and but destination type contains null. as does not do any coercions.
  • Removed the | syntax for indicating named parameters. All optional parameters are now also named.
  • The arguments local variable is now supported only for unchecked functions.
  • Modified the syntax of the semantics to better match the ECMAScript Edition 3 style. Partially updated the notation page.
  • Fixed a bug in the unit semantics.
  • Note: Not all of the decisions reached in the last two ECMA TC39TG1 meetings have been integrated into this document yet.
Mar 9, 2001
  • Added link to the preliminary draft of the specification in PDF format.
  • Minor editorial changes.
Mar 2, 2001
Feb 28, 2001
  • Created the syntactic semantics. It’s still a work in progress.
  • Updated the execution stages page.
  • Added mutable cells and the associated operators to the semantic notation.
  • Renamed the Double semantic type to Float64 (this affects the semantics only, not the JavaScript language).
  • Added many Float64 manipulation functions.
  • Made minor stylistic changes throughout the document.
Feb 22, 2001
  • Renamed type None to Never.
  • Renamed the empty escape from \Q to \_.
Feb 8, 2001
Feb 6, 2001
  • Updated the definition extent model as discussed at the January TC39TG1 meeting. Now definitions are local by default but hoist if necessary. Removed the regional and global attributes.
  • Updated the definition conflict rules: added the rule about non-interfering local definitions and removed the rule about permitting re-execution of a const definition, since that is now impossible.
  • Removed the paragraph about JavaScript 2.0 being firmly in the dynamic camp from the introduction, since the examples given — dynamically defining classes and functions by placing them inside an if statement — no longer apply. Some of this can still be done using boolean attributes, but these attributes must be compile-time expressions.
  • Changed the data structures returned by methods of the for-in iteration protocol to be objects with named properties value and state rather than arrays or tuples with numbered properties 0 and 1. This allows the two properties to be declared using different types.
  • Specified a default superconstructor call if a constructor contains no other superconstructor calls.
  • Specified that object construction follows the Java model rather than the C++ model — when a constructor calls a virtual method on an object o under construction, it sees the most derived method even if the class in which that method is located has not yet run its constructor on o.
  • Added vector comprehensions [g(a| a  u] and [g(a| a  u and c(a)] to the semantic notation.
Jan 31, 2001
  • Eliminated namespace inheritance to simplify the proposal. This is unnecessary given the ability to use const to combine several namespace attributes.
  • Removed property lookups using a class before the :: (x.C::n and super x.C::n where C is a class). This feature did not add much useful functionality.
Jan 25, 2001
  • Minor wording changes.
  • Brought back the .() operator.
  • Updated semantic notation — revised description and usage of and added unique id’s.
Jan 11, 2001
  • In strict mode the default scope is local everywhere.
  • Like in C++, for statements now form their own scopes. This affects local definitions only.
  • catch clauses now form their own scopes.
  • try statements no longer allow annotations on any of their constituent blocks.
  • Split the notion of statements into statements and directives. Directives (including most definitions) can only be at the top level of a block, while statements can be anywhere. This avoids the problem of conditional definitions as substatements of a compound statement.
  • Reorganized the statement grammar around the distinction between statements and directives. Added the Substatement nonterminal.
  • Revised the discussion of annotated blocks.
  • Revised the description of scopes.
  • Added an optional const attribute to function parameters, which makes them read-only.
Jan 9, 2001
  • Made the attribute weak JS-only.
  • Made minor clarifications without affecting the content.
  • Added rationale for the types Object and None.
  • Added attribute-style alternative to the type syntax rationale. Feedback on this style would be appreciated.
  • Revamped variable lookup to search for instance members inside instance methods without the need for the this. prefix. Also moved the description of the lookup of static members inside a class’s scope from the class section to the variable lookup section.
  • Simplified the package referencing rules. Also fixed the examples there to not use a package as a :: qualifier, since one is not allowed there by the name lookup rules.
  • Changed explicit from a specialized attribute into a namespace similar to internal. Removed implicit. This simplified the name lookup rules.
  • Greatly simplified use’s included and excluded name possibilities to be either * or a list of identifiers.
  • Generalized the iteration protocol to allow its methods to return objects of any type as long as they have the properties 0 and 1. Stated that the values returned by the iteration protocol expire when the next iteration occurs.
  • Added rationale for not overriding !, ||, ^^, &&, and ?:.
Dec 21, 2000
Dec 20, 2000
  • Made minor wording fixes in the packages section.
  • Simplified the grammar by making the const operator have the same precedence as the other unary operators. When used as a type constructor, the const operator now applies to the array type instead of the element type. The const operator can no longer be used to emulate the const statement.
  • Simplified the IncludesExcludes grammar without changing its behavior in any significant way by merging it with the expression grammar.
Dec 18, 2000
  • Changed the syntax for defining an operator override from function operator "op" to operator function "op". operator is now an attribute instead of a keyword.
  • Renamed operator overloading to operator overriding. Moved the operators page from the libraries to the core section.
  • Removed the Boolean return type restriction from the <, <=, ==, ===, and in operators.
  • Restricted the === operator to take operands of the same class.
  • Modified single and double operator dispatch rules so that null is considered to be a member of only the types Null and Object. Without this restriction dispatch becomes ambiguous. Note that ordinary method dispatch already has this restriction built-in.
  • Specified the built-in operator definitions.
Dec 2, 2000
  • Revamped the syntax for operator overriding based on feedback from the last ECMA meeting. There is now a special syntax to do this.
  • Modified the syntax for accessing a superclass’s method to conform to the new operator overriding scheme. The super::id syntax is no longer supported. super is now an operator modifier that alters the behavior of another operator such as . (property lookup) or any of the overridable operators such as +.
  • Updated the property lookup section to accommodate the new super syntax.
Nov 29, 2000
  • Revamped property lookup. For an unqualified reference x.n, instance name lookup previously found the most derived property. Now it first looks for the least derived property and picks the most derived overload of that property. The new definition handles private property access correctly and allows property access to be optimized to a simple offset lookup when the static type of the instance is known.
  • For simplicity removed the C::n (where C is a class) case of variable lookup. Use C.n instead.
  • Added descriptions of instances, properties, and property names.
  • Stated that the activation frame of a class contains aliases to the superclass’s global members.
  • Cleaned up nomenclature: the names defined by a class are members, while the bindings inside an object are properties. Members cause properties to be constructed when a class instance is created.
Nov 20, 2000
  • Renamed the s regular expression flag from simple to span.
  • Removed the /UnitProduct production from the unit grammar.
  • Allowed white space in the unit grammar. White space can now also be used to indicate implicit multiplication there.
  • Fixed the product rule in the unit grammar.
  • Renamed expt to pow in unit expressions.
Nov 4, 2000
  • Added attributes true and false.
  • Replaced the qualified attribute by the include and exclude syntax in import and use namespace statements. Added nonreserved words include and exclude.
  • Imported definitions appear in the global scope instead of the scope of the import statement; however, the implicit use still applies to scope of the import statement.
  • Predefined type names are constants in the global scope instead of a scope enclosing the global scope.
  • Defined activation frames and qualified names.
  • Blocks with attributes are not scopes.
  • Eliminated the notion of the static and dynamic extent of a definition. Rewrote and corrected the definition extent and name lookup rules in terms of scopes and activation frames only.
  • Simplified name lookup rules, making them independent of the order in which namespaces are used.
  • Relaxed the compile-time constant rules to permit expressions that either return a known value or signal an error. Without this change packages and namespaces cannot work.
  • A class can be used instead of a namespace before the :: during name lookup. This limits the search to members of that class or its superclasses.
  • Eliminated the a::b::c syntactic sugar. In the rare cases where it’s still needed, use (a.b)::c.
  • Defining b::n when there is already a definition a::n in the same scope causes an error if both namespaces a and b are used at the point of the definition of b::n.
  • Renamed scope to regional. scope blocks can now be either local or regional blocks. Defined the notion of a regional scope.
  • Changed unit lookup to look in the Unit class instead of prefixing unit_ to each unit name and looking for a global symbol. Added the unit attribute.
  • In strict mode the default scope is local only inside functions.
  • Strict mode is optional (ECMAScript only).
Oct 27, 2000
  • Expanded the qualified attribute to optionally take a list of symbols to exclude.
  • Definitions of top-level entities in a package can only be placed in the namespace public or in namespaces defined within that package.
  • Extensively modified and updated the description of units. Allowed multiple unit on the same expression in order to support combining number class units (such as "decimal") with units of measure. Defined the grammar and semantics of unit expressions.
Oct 10, 2000
  • Removed the primitive attribute.
  • Defined methods for overriding the for-in operator.
  • Added the s (simple) flag to regular expressions. This flag makes . match every character.
Oct 9, 2000
  • Made classof, eval, and include no longer be reserved words.
  • Combined the import statement with an automatic use namespace of selected namespaces.
  • Made the include statement take string literals only.
  • Changed classof x to x.class.
  • Fixed minor editing errors.
Sep 23, 2000
  • Defined coercions of undefined to any type except None.
  • Renamed the none and void types to None and Void. Now all predefined type names start with upper case letters.
  • Removed the singleton type.
  • Resurrected the ECMAScript Edition 3 void operator and added the classof operator.
  • Made default constructors accept named arguments.
  • Modified the syntax of class extensions and moved their description to the definitions page.
  • Changed the meaning of a::b::c to be (a.b)::c rather than the intersection of the a::c and b::c sets. This means that an identifier may be qualified by only one namespace.
  • Updated the compatibility, namespace, operator overloading, and versioning pages.
Sep 22, 2000
Sep 21, 2000
  • Updated list of reserved words.
  • Updated concept page.
  • Renamed volatile to virtual, keeping volatile’s old semantics.
  • Revamped list and descriptions of attributes. Added a number of new attributes.
  • Disallowed qualifiers in names of literal object fields and names of arguments. Allowed parenthesized indirect expressions that evaluate to strings in those cases.
  • Added const operator, array types, and const array types.
  • Added include statement.
  • Changed the handling of the rest parameter to only accept named arguments if it’s preceded by a |.
Sep 18, 2000 Integrated many changes based on recent discussions with Herman and others:
  • Renamed any to Object.
  • Added notion of live and dead statements.
  • Required attributes to be compile-time constants.
  • Reinstated parenthesized expressions before :: (except in attributes).
  • Changed package names in package definitions to be identifiers or dotted identifier lists. This required renaming the package attribute to internal in order to keep the grammar LR(1)-parsable.
  • Renamed import to qualified import and use import to import.
  • Allowed super.foo as an abbreviation for this.super::foo.
  • Removed obj.(expr) member access syntax.
  • Removed definitions that define qualified identifiers.
  • Required const declarations to have initializers.
  • Each block is its own scope in strict mode.
  • Specified the means of defining parameters that take named arguments. Rewrote description of argument passing.
  • Cleaned up significant portions of the grammar.
Aug 21, 2000
  • Significantly reworked syntax of attributes and expressions to allow attributes to take arguments. This required making constructor, namespace, and use into reserved words.
  • Required parentheses after eval.
  • Removed the syntaxes for placing a parenthesized expression before :: and for unquoted package names due to grammar conflicts.
  • Removed the attribute keyword; attributes are now defined using the const syntax.
  • Removed compile blocks.
  • Added the \Q escape, which turns into nothing and is useful for using identifiers that would otherwise be reserved words.
Aug 17, 2000 Split off ECMAScript Edition 4 proposal.
Aug 11, 2000 Reformatted site for compatibility with Navigator 6 and Internet Explorer. Archived third draft.
Jun 6, 2000 Added discussion of constant expressions and related restrictions on the expressions page. Defined the [] operator. Added visibility modifier attributes.
May 26, 2000 Minor grammar changes and cleanups. Allowed attributes in var and const declarations in for statements. Added [no line break] assertions in various rules to prevent changing the meaning of JavaScript 1.5 programs. Simplified switch and block grammars without changing their meanings.
May 8, 2000 Changed the name of a default constructor from new to the same name as its class. This eliminated the various syntactic special cases of new in places where a member name was expected. Also allowed qualified identifiers as literal field names.
May 1, 2000 Rewrote packages page.
Apr 30, 2000 Made significant syntax changes (Parser Grammar and other pages): revised identifier qualifiers, primary expressions, and definition attributes; added attribute, namespace, interface, import, export, and use statements; changed package naming. Updated definition of scopes and namespaces on Concepts page. Updated list of keywords on Lexer page. Revised definition extent rules. Allowed multiple const, class, and interface declarations as long as only one is a definition. Rewrote variables, functions, definitions, and classes pages.
Feb 16, 2000 Updated machine type and operator overloading pages.
Feb 15, 2000 Updated grammar and discussions of concepts, types, expressions, statements, definitions, and variables, as well as the syntax rationale.
Dec 7, 1999 Removed field, method, and constructor from the semantics and replaced with creative uses of the static prefix.
Nov 11, 1999 Continuing major reorganization of this document....
Nov 5, 1999 Reorganized the document’s structure into chapters. Structured the core language chapter more in the bottom-up style of the ECMAScript standard than in the previous issue-oriented style. Combined and moved rationales and issues into an appendix. Added introduction page. Removed or reworded many obsolete paragraphs throughout the document.
Nov 2, 1999 Modified the parser grammar: added [no line break] constraints, removed version lists after public keywords, added box and user-defined visibility keywords, and added named function arguments.
Oct 29, 1999 Revised the execution model based on recent ECMA modularity group discussions. JavaScript 2.0 now has a hybrid execution model instead of a pure dynamic one, which allows for better compatibility with JavaScript 1.5.
Oct 20, 1999 Added throw and try-catch semantic operators to semantic notation and used them to signal syntax errors detected by the semantics that would be impossible or too messy to detect in the grammars. Updated formal description pages to match recent ECMA TC39 subcommittee decisions: eliminated octal numbers and escapes (both in strings and in regular expressions) to match ECMAScript Edition 3, switched to using the Identifier : TypeExpression syntax for type declarations, and added local blocks and the local visibility specifier. Also simplified the parser grammar for definitions and removed the « and » syntax for regular expression literals.
Jul 26, 1999 Wrote description of semantic notation. Updated grammar notation page to describe lookahead constraints. Updated regular expression semantics to match ECMA working group decisions for ECMAScript Edition 3; one of these included changing the behavior of (?= to not backtrack.
Jun 7, 1999 Revised all grammars and semantics to simplify the grammars. Fixed several errors and omissions in the regular expression grammar and semantics. Added support for (?= and (?!.
May 16, 1999 Added regular expression grammar and semantics.
May 12, 1999 Added preliminary Formal Description chapter.
Mar 25, 1999 Added Member Lookup page. Released second draft.
Mar 24, 1999 Added many clarifications, discussion sections, and small changes throughout the pages.
Mar 23, 1999 Rewrote Execution Model page and split it off from the Definitions page. Added discussion of float to Machine Types.
Mar 22, 1999 Removed numbered versions from the Versions page; added motivation, discussion, and version aliasing using =. Removed angle brackets < and > from VersionsAndRenames.
Mar 16, 1999 Rewrote Types page. Split off byte, ubyte, short, ushort, int, uint, long, ulong into an optional Machine Types library.
Feb 18, 1999 Released first draft.

Waldemar Horwat
Last modified Monday, April 22, 2002