Annex B (normative) Additional ECMAScript Features for Web Browsers

The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript host is a web browser. The content of this annex is normative but optional if the ECMAScript host is not a web browser.

NOTE This annex describes various legacy features and other characteristics of web browser based ECMAScript implementations. All of the language features and behaviours specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification. However, the usage of these features by large numbers of existing web pages means that web browsers must continue to support them. The specifications in this annex defined the requirements for interoperable implementations of these legacy features.

These features are not considered part of the core ECMAScript language. Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. ECMAScript implementations are discouraged from implementing these features unless the implementation is part of a web browser or is required to run the same legacy ECMAScript code that web browsers encounter.

B.1 Additional Syntax

B.1.1 Numeric Literals

The syntax and semantics of 11.8.3 is extended as follows except that this extension is not allowed for strict mode code:

Syntax

NumericLiteral ::
DecimalLiteral
BinaryIntegerLiteral
OctalIntegerLiteral
HexIntegerLiteral
LegacyOctalIntegerLiteral
LegacyOctalIntegerLiteral ::
0 OctalDigit
LegacyOctalIntegerLiteral OctalDigit
DecimalIntegerLiteral ::
0
NonZeroDigit DecimalDigitsopt
NonOctalDecimalIntegerLiteral
NonOctalDecimalIntegerLiteral ::
0 NonOctalDigit
LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit
NonOctalDecimalIntegerLiteral DecimalDigit
LegacyOctalLikeDecimalIntegerLiteral ::
0 OctalDigit
LegacyOctalLikeDecimalIntegerLiteral OctalDigit
NonOctalDigit :: one of
8 9

B.1.1.1 Static Semantics

  • The MV of LegacyOctalIntegerLiteral :: 0 OctalDigit is the MV of OctalDigit.

  • The MV of LegacyOctalIntegerLiteral :: LegacyOctalIntegerLiteral OctalDigit is (the MV of LegacyOctalIntegerLiteral times 8) plus the MV of OctalDigit.

  • The MV of DecimalIntegerLiteral :: NonOctalDecimalIntegerLiteral is the MV of NonOctalDecimalIntegerLiteral.

  • The MV of NonOctalDecimalIntegerLiteral :: 0 NonOctalDigit is the MV of NonOctalDigit.

  • The MV of NonOctalDecimalIntegerLiteral :: LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit is (the MV of LegacyOctalLikeDecimalIntegerLiteral times 10) plus the MV of NonOctalDigit.

  • The MV of NonOctalDecimalIntegerLiteral :: NonOctalDecimalIntegerLiteral DecimalDigit is (the MV of NonOctalDecimalIntegerLiteral times 10) plus the MV of DecimalDigit.

  • The MV of LegacyOctalLikeDecimalIntegerLiteral :: 0 OctalDigit is the MV of OctalDigit.

  • The MV of LegacyOctalLikeDecimalIntegerLiteral :: LegacyOctalLikeDecimalIntegerLiteral OctalDigit is (the MV of LegacyOctalLikeDecimalIntegerLiteral times 10) plus the MV of OctalDigit.

  • The MV of NonOctalDigit :: 8 is 8.

  • The MV of NonOctalDigit :: 9 is 9.

B.1.2 String Literals

The syntax and semantics of 11.8.4 is extended as follows except that this extension is not allowed for strict mode code:

Syntax

EscapeSequence ::
CharacterEscapeSequence
LegacyOctalEscapeSequence
HexEscapeSequence
UnicodeEscapeSequence
LegacyOctalEscapeSequence ::
OctalDigit [lookahead ∉ OctalDigit]
ZeroToThree OctalDigit [lookahead ∉ OctalDigit]
FourToSeven OctalDigit
ZeroToThree OctalDigit OctalDigit
ZeroToThree :: one of
0 1 2 3
FourToSeven :: one of
4 5 6 7

This definition of EscapeSequence is not used in strict mode or when parsing TemplateCharacter (11.8.6).

B.1.2.1 Static Semantics

  • The SV of EscapeSequence :: LegacyOctalEscapeSequence is the SV of the LegacyOctalEscapeSequence.
  • The SV of LegacyOctalEscapeSequence :: OctalDigit is the code unit whose value is the MV of the OctalDigit.
  • The SV of LegacyOctalEscapeSequence :: ZeroToThree OctalDigit is the code unit whose value is (8 times the MV of the ZeroToThree) plus the MV of the OctalDigit.
  • The SV of LegacyOctalEscapeSequence :: FourToSeven OctalDigit is the code unit whose value is (8 times the MV of the FourToSeven) plus the MV of the OctalDigit.
  • The SV of LegacyOctalEscapeSequence :: ZeroToThree OctalDigit OctalDigit is the code unit whose value is (64 (that is, 82) times the MV of the ZeroToThree) plus (8 times the MV of the first OctalDigit) plus the MV of the second OctalDigit.
  • The MV of ZeroToThree :: 0 is 0.
  • The MV of ZeroToThree :: 1 is 1.
  • The MV of ZeroToThree :: 2 is 2.
  • The MV of ZeroToThree :: 3 is 3.
  • The MV of FourToSeven :: 4 is 4.
  • The MV of FourToSeven :: 5 is 5.
  • The MV of FourToSeven :: 6 is 6.
  • The MV of FourToSeven :: 7 is 7.

B.1.3 HTML-like Comments

The syntax and semantics of 11.4 is extended as follows except that this extension is not when parsing source code using the goal symbol Module :

Syntax

Comment ::
MultiLineComment
SingleLineComment
SingleLineHTMLOpenComment
SingleLineHTMLCloseComment
SingleLineDelimitedComment
MultiLineComment ::
/* FirstCommentLineopt LineTerminator MultiLineCommentCharsopt */ HTMLCloseCommentopt
FirstCommentLine ::
SingleLineDelimitedCommentChars
SingleLineHTMLOpenComment ::
<!-- SingleLineCommentCharsopt
SingleLineHTMLCloseComment ::
LineTerminatorSequence HTMLCloseComment
SingleLineDelimitedComment ::
/* SingleLineDelimitedCommentCharsopt */
HTMLCloseComment ::
WhiteSpaceSequenceopt SingleLineDelimitedCommentSequenceopt --> SingleLineCommentCharsopt
SingleLineDelimitedCommentChars ::
SingleLineNotAsteriskChar SingleLineDelimitedCommentCharsopt
* SingleLinePostAsteriskCommentCharsopt
SingleLineNotAsteriskChar ::
SourceCharacter but not one of * or LineTerminator
SingleLinePostAsteriskCommentChars ::
SingleLineNotForwardSlashOrAsteriskChar SingleLineDelimitedCommentCharsopt
* SingleLinePostAsteriskCommentCharsopt
SingleLineNotForwardSlashOrAsteriskChar ::
SourceCharacter but not one of / or * or LineTerminator
WhiteSpaceSequence ::
WhiteSpace WhiteSpaceSequenceopt
SingleLineDelimitedCommentSequence ::
SingleLineDelimitedComment WhiteSpaceSequenceopt SingleLineDelimitedCommentSequenceopt

Similar to a MultiLineComment that contains a line terminator code point, a SingleLineHTMLCloseComment is considered to be a LineTerminator for purposes of parsing by the syntactic grammar.

B.1.4 Regular Expressions Patterns

The syntax of 21.2.1 is modified and extended as follows. These changes introduce ambiguities that are broken by the ordering of grammar productions and by contextual information. When parsing using the following grammar, each alternative is considered only if previous production alternatives do not match.

This alternative pattern grammar and semantics only changes the syntax and semantics of BMP patterns. The following grammar extensions include productions parameterized with the [U] parameter. However, none of these extensions change the syntax of Unicode patterns recognized when parsing with the [U] parameter present on the goal symbol.

Syntax

Term[U] ::
[~U] ExtendedTerm
[+U] Assertion[U]
[+U] Atom[U]
[+U] Atom[U] Quantifier
ExtendedTerm ::
Assertion
AtomNoBrace Quantifier
Atom
QuantifiableAssertion Quantifier
AtomNoBrace ::
PatternCharacterNoBrace
.
\ AtomEscape
CharacterClass
( Disjunction )
( ? : Disjunction )
Atom[U] ::
PatternCharacter
.
\ AtomEscape[?U]
CharacterClass[?U]
( Disjunction[?U] )
( ? : Disjunction[?U] )
PatternCharacterNoBrace ::
SourceCharacter but not one of
^ $ \ . * + ? ( ) [ ] { } |
PatternCharacter ::
SourceCharacter but not one of
^ $ \ . * + ? ( ) [ ] |
QuantifiableAssertion ::
( ? = Disjunction )
( ? ! Disjunction )
Assertion[U] ::
^
$
\ b
\ B
[+U] ( ? = Disjunction[U] )
[+U] ( ? ! Disjunction[U] )
[~U] QuantifiableAssertion
AtomEscape[U] ::
[+U] DecimalEscape
[+U] CharacterEscape[U]
[+U] CharacterClassEscape
[~U] DecimalEscape but only if the integer value of DecimalEscape is <= NCapturingParens
[~U] CharacterClassEscape
[~U] CharacterEscape
CharacterEscape[U] ::
ControlEscape
c ControlLetter
HexEscapeSequence
RegExpUnicodeEscapeSequence[?U]
[~U] LegacyOctalEscapeSequence
IdentityEscape[?U]
IdentityEscape[U] ::
[+U] SyntaxCharacter
[+U] /
[~U] SourceCharacter but not c
NonemptyClassRanges[U] ::
ClassAtom[?U]
ClassAtom[?U] NonemptyClassRangesNoDash[?U]
[+U] ClassAtom[U] - ClassAtom[U] ClassRanges[U]
[~U] ClassAtomInRange - ClassAtomInRange ClassRanges
NonemptyClassRangesNoDash[U] ::
ClassAtom[?U]
ClassAtomNoDash[?U] NonemptyClassRangesNoDash[?U]
[+U] ClassAtomNoDash[U] - ClassAtom[U] ClassRanges[U]
[~U] ClassAtomNoDashInRange - ClassAtomInRange ClassRanges
ClassAtom[U] ::
-
ClassAtomNoDash[?U]
ClassAtomNoDash[U] ::
SourceCharacter but not one of \ or ] or -
\ ClassEscape[?U]
ClassAtomInRange ::
-
ClassAtomNoDashInRange
ClassAtomNoDashInRange ::
SourceCharacter but not one of \ or ] or -
\ ClassEscape but only if ClassEscape evaluates to a CharSet with exactly one character
\ IdentityEscape
ClassEscape[U] ::
[+U] DecimalEscape
[+U] CharacterEscape[U]
[+U] CharacterClassEscape
[~U] DecimalEscape
b
[~U] CharacterClassEscape
[~U] CharacterEscape

NOTE When the same left hand sides occurs with both [+U] and [~U] guards it is to control the disambiguation priority.

B.1.4.1 Pattern Semantics

The semantics of 21.2.2 is extended as follows:

Within 21.2.2.5 reference to “Atom :: ( Disjunction ) ” are to be interpreted as meaning “Atom :: ( Disjunction ) ” or “AtomNoBrace :: ( Disjunction ) ”.

Term (21.2.2.5) includes the following additional evaluation rule:

The production Term :: QuantifiableAssertion Quantifier evaluates the same as the production Term :: Atom Quantifier but with QuantifiableAssertion substituted for Atom.

Atom (21.2.2.8) evaluation rules for the Atom productions except for Atom :: PatternCharacter are also used for the AtomNoBrace productions, but with AtomNoBrace substituted for Atom. The following evaluation rule is also added:

The production AtomNoBrace :: PatternCharacterNoBrace evaluates as follows:

  1. Let ch be the character represented by PatternCharacterNoBrace.
  2. Let A be a one-element CharSet containing the character ch.
  3. Call CharacterSetMatcher(A, false) and return its Matcher result.

CharacterEscape (21.2.2.10) includes the following additional evaluation rule:

The production CharacterEscape :: LegacyOctalEscapeSequence evaluates by evaluating the SV of the LegacyOctalEscapeSequence (see B.1.2) and returning its character result.

ClassAtom (21.2.2.17) includes the following additional evaluation rules:

The production ClassAtomInRange :: - evaluates by returning the CharSet containing the one character -.

The production ClassAtomInRange :: ClassAtomNoDashInRange evaluates by evaluating ClassAtomNoDashInRange to obtain a CharSet and returning that CharSet.

ClassAtomNoDash (21.2.2.18) includes the following additional evaluation rules:

The production ClassAtomNoDashInRange :: SourceCharacter but not one of \ or ] or - evaluates by returning a one-element CharSet containing the character represented by SourceCharacter.

The production ClassAtomNoDashInRange :: \ ClassEscape but only if…, evaluates by evaluating ClassEscape to obtain a CharSet and returning that CharSet.

The production ClassAtomNoDashInRange :: \ IdentityEscape evaluates by returning the character represented by IdentityEscape.

B.2 Additional Built-in Properties

When the ECMAScript host is a web browser the following additional properties of the standard built-in objects are defined.

B.2.1 Additional Properties of the Global Object

The entries in Table 60 are added to Table 7.

Table 60 — Additional Well-known Intrinsic Objects
Intrinsic Name Global Name ECMAScript Language Association
%escape% escape The escape function (B.2.1.1)
%unescape% unescape The unescape function (B.2.1.2)

B.2.1.1 escape (string)

The escape function is a property of the global object. It computes a new version of a String value in which certain code units have been replaced by a hexadecimal escape sequence.

For those code units being replaced whose value is 0x00FF or less, a two-digit escape sequence of the form %xx is used. For those characters being replaced whose code unit value is greater than 0x00FF, a four-digit escape sequence of the form %uxxxx is used.

The escape function is the %escape% intrinsic object. When the escape function is called with one argument string, the following steps are taken:

  1. Let string be ToString(string).
  2. ReturnIfAbrupt(string).
  3. Let length be the number of code units in string.
  4. Let R be the empty string.
  5. Let k be 0.
  6. Repeat, while k < length,
    1. Let char be the code unit (represented as a 16-bit unsigned integer) at index k within string.
    2. If char is one of the code units in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./", then
      1. Let S be a String containing the single code unit char.
    3. Else if char ≥ 256, then
      1. Let S be a String containing six code units "%uwxyz" where wxyz are the code units of the four hexadecimal digits encoding the value of char.
    4. Else, char < 256
      1. Let S be a String containing three code units "%xy" where xy are the code units of two hexadecimal digits encoding the value of char.
    5. Let R be a new String value computed by concatenating the previous value of R and S.
    6. Increase k by 1.
  7. Return R.

NOTE The encoding is partly based on the encoding described in RFC 1738, but the entire encoding specified in this standard is described above without regard to the contents of RFC 1738. This encoding does not reflect changes to RFC 1738 made by RFC 3986.

B.2.1.2 unescape (string)

The unescape function is a property of the global object. It computes a new version of a String value in which each escape sequence of the sort that might be introduced by the escape function is replaced with the code unit that it represents.

The unescape function is the %unescape% intrinsic object. When the unescape function is called with one argument string, the following steps are taken:

  1. Let string be ToString(string).
  2. ReturnIfAbrupt(string).
  3. Let length be the number of code units in string.
  4. Let R be the empty String.
  5. Let k be 0.
  6. Repeat, while klength
    1. Let c be the code unit at index k within string.
    2. If c is %,
      1. If klength−6 and the code unit at index k+1 within string is u and the four code units at indices k+2, k+3, k+4, and k+5 within string are all hexadecimal digits, then
        1. Let c be the code unit whose value is the integer represented by the four hexadecimal digits at indices k+2, k+3, k+4, and k+5 within string.
        2. Increase k by 5.
      2. Else if klength−3 and the two code units at indices k+1 and k+2 within string are both hexadecimal digits, then
        1. Let c be the code unit whose value is the integer represented by two zeroes plus the two hexadecimal digits at indices k+1 and k+2 within string.
        2. Increase k by 2.
    3. Let R be a new String value computed by concatenating the previous value of R and c.
    4. Increase k by 1.
  7. Return R.

B.2.2 Additional Properties of the Object.prototype Object

B.2.2.1 Object.prototype.__proto__

Object.prototype.__proto__ is an accessor property with attributes { [[Enumerable]]: false, [[Configurable]]: true }. The [[Get]] and [[Set]] attributes are defined as follows

B.2.2.1.1 get Object.prototype.__proto__

The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps:

  1. Let O be ToObject(this value).
  2. ReturnIfAbrupt(O).
  3. Return O.[[GetPrototypeOf]]().

B.2.2.1.2 set Object.prototype.__proto__

The value of the [[Set]] attribute is a built-in function that takes an argument proto. It performs the following steps:

  1. Let O be RequireObjectCoercible(this value).
  2. ReturnIfAbrupt(O).
  3. If Type(proto) is neither Object nor Null, return undefined.
  4. If Type(O) is not Object, return undefined.
  5. Let status be O.[[SetPrototypeOf]](proto).
  6. ReturnIfAbrupt(status).
  7. If status is false, throw a TypeError exception.
  8. Return undefined.

B.2.3 Additional Properties of the String.prototype Object

B.2.3.1 String.prototype.substr (start, length)

The substr method takes two arguments, start and length, and returns a substring of the result of converting the this object to a String, starting from index start and running for length code units (or through the end of the String if length is undefined). If start is negative, it is treated as (sourceLength+start) where sourceLength is the length of the String. The result is a String value, not a String object. The following steps are taken:

  1. Let O be RequireObjectCoercible(this value).
  2. Let S be ToString(O).
  3. ReturnIfAbrupt(S).
  4. Let intStart be ToInteger(start).
  5. ReturnIfAbrupt(intStart).
  6. If length is undefined, let end be +∞; otherwise let end be ToInteger(length).
  7. ReturnIfAbrupt(end).
  8. Let size be the number of code units in S.
  9. If intStart < 0, let intStart be max(size + intStart,0).
  10. Let resultLength be min(max(end,0), sizeintStart).
  11. If resultLength ≤ 0, return the empty String "".
  12. Return a String containing resultLength consecutive code units from S beginning with the code unit at index intStart.

The length property of the substr method is 2.

NOTE The substr function is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

B.2.3.2 String.prototype.anchor ( name )

When the anchor method is called with argument name, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "a", "name", name).

B.2.3.2.1 Runtime Semantics: CreateHTML ( string, tag, attribute, value )

The abstract operation CreateHTML is called with arguments string, tag, attribute, and value. The arguments tag and attribute must be String values. The following steps are taken:

  1. Let str be RequireObjectCoercible(string).
  2. Let S be ToString(str).
  3. ReturnIfAbrupt(S).
  4. Let p1 be the String value that is the concatenation of "<" and tag.
  5. If attribute is not the empty String, then
    1. Let V be ToString(value).
    2. ReturnIfAbrupt(V).
    3. Let escapedV be the String value that is the same as V except that each occurrence of the code unit 0x0022 (QUOTATION MARK) in V has been replaced with the six code unit sequence "&quot;".
    4. Let p1 be the String value that is the concatenation of the following String values:
      • The String value of p1
      • Code unit 0x0020 (SPACE)
      • The String value of attribute
      • Code unit 0x003D (EQUALS SIGN)
      • Code unit 0x0022 (QUOTATION MARK)
      • The String value of escapedV
      • Code unit 0x0022 (QUOTATION MARK)
  6. Let p2 be the String value that is the concatenation of p1 and ">".
  7. Let p3 be the String value that is the concatenation of p2 and S.
  8. Let p4 be the String value that is the concatenation of p3, "</", tag, and ">".
  9. Return p4.

B.2.3.3 String.prototype.big ()

When the big method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "big", "", "").

B.2.3.5 String.prototype.bold ()

When the bold method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "b", "", "").

B.2.3.6 String.prototype.fixed ()

When the fixed method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "tt", "", "").

B.2.3.7 String.prototype.fontcolor ( color )

When the fontcolor method is called with argument color, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "font", "color", color).

B.2.3.8 String.prototype.fontsize ( size )

When the fontsize method is called with argument size, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "font", "size", size).

B.2.3.9 String.prototype.italics ()

When the italics method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "i", "", "").

B.2.3.11 String.prototype.small ()

When the small method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "small", "", "").

B.2.3.12 String.prototype.strike ()

When the strike method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "strike", "", "").

B.2.3.13 String.prototype.sub ()

When the sub method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "sub", "", "").

B.2.3.14 String.prototype.sup ()

When the sup method is called with no arguments, the following steps are taken:

  1. Let S be the this value.
  2. Return CreateHTML(S, "sup", "", "").

B.2.4 Additional Properties of the Date.prototype Object

B.2.4.1 Date.prototype.getYear ( )

NOTE The getFullYear method is preferred for nearly all purposes, because it avoids the “year 2000 problem.”

When the getYear method is called with no arguments, the following steps are taken:

  1. Let t be this time value.
  2. ReturnIfAbrupt(t).
  3. If t is NaN, return NaN.
  4. Return YearFromTime(LocalTime(t)) − 1900.

B.2.4.2 Date.prototype.setYear (year)

NOTE The setFullYear method is preferred for nearly all purposes, because it avoids the “year 2000 problem.”

When the setYear method is called with one argument year, the following steps are taken:

  1. Let t be this time value.
  2. ReturnIfAbrupt(t).
  3. If t is NaN, let t be +0; otherwise, let t be LocalTime(t).
  4. Let y be ToNumber(year).
  5. ReturnIfAbrupt(y).
  6. If y is NaN, set the [[DateValue]] internal slot of this Date object to NaN and return NaN.
  7. If y is not NaN and 0 ≤ ToInteger(y) ≤ 99, let yyyy be ToInteger(y) + 1900.
  8. Else, let yyyy be y.
  9. Let d be MakeDay(yyyy, MonthFromTime(t), DateFromTime(t)).
  10. Let date be UTC(MakeDate(d, TimeWithinDay(t))).
  11. Set the [[DateValue]] internal slot of this Date object to TimeClip(date).
  12. Return the value of the [[DateValue]] internal slot of this Date object.

B.2.4.3 Date.prototype.toGMTString ( )

NOTE The property toUTCString is preferred. The toGMTString property is provided principally for compatibility with old code. It is recommended that the toUTCString property be used in new ECMAScript code.

The function object that is the initial value of Date.prototype.toGMTString is the same function object that is the initial value of Date.prototype.toUTCString.

B.2.5 Additional Properties of the RegExp.prototype Object

B.2.5.1 RegExp.prototype.compile (pattern, flags )

When the compile method is called with arguments pattern and flags, the following steps are taken:

  1. Let O be the this value.
  2. If Type(O) is not Object or Type(O) is Object and O does not have a [[RegExpMatcher]] internal slot, then
    1. Throw a TypeError exception.
  3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal slot, then
    1. If flags is not undefined, throw a TypeError exception.
    2. Let P be the value of pattern’s [[OriginalSource]] internal slot.
    3. Let F be the value of pattern’s [[OriginalFlags]] internal slot.
  4. Else,
    1. Let P be pattern.
    2. Let F be flags.
  5. Return RegExpInitialize(O, P, F).

NOTE The compile method completely reinitializes the this object RegExp with a new pattern and flags. An implementation may interpret use of this method as an assertion that the resulting RegExp object will be used multiple times and hence is a candidate for extra optimization.

B.3 Other Additional Features

B.3.1 __proto__ Property Names in Object Initializers

The following Early Error rule is added to those in 12.2.6.1:

ObjectLiteral : { PropertyDefinitionList }ObjectLiteral : { PropertyDefinitionList , }

  • It is a Syntax Error if PropertyNameList of PropertyDefinitionList contains any duplicate entries for "__proto__" and at least two of those entries were obtained from productions of the form PropertyDefinition : PropertyName : AssignmentExpression .

NOTE The List returned by PropertyNameList does not include string literal property names defined as using a ComputedPropertyName.

In 12.2.6.9 the PropertyDefinitionEvaluation algorithm for the production
PropertyDefinition : PropertyName : AssignmentExpression
is replaced with the following definition:

PropertyDefinition : PropertyName : AssignmentExpression
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. Let exprValueRef be the result of evaluating AssignmentExpression.
  4. Let propValue be GetValue(exprValueRef).
  5. ReturnIfAbrupt(propValue).
  6. If propKey is the String value "__proto__" and if IsComputedPropertyKey(propKey) is false, then
    1. If Type(propValue) is either Object or Null, then
      1. Return object.[[SetPrototypeOf]](propValue).
    2. Return NormalCompletion(empty).
  7. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let hasNameProperty be HasOwnProperty(propValue, "name").
    2. ReturnIfAbrupt(hasNameProperty).
    3. If hasNameProperty is false, perform SetFunctionName(propValue, propKey).
  8. Assert: enumerable is true.
  9. Return CreateDataPropertyOrThrow(object, propKey, propValue).

B.3.2 Labelled Function Declarations

Prior to ECMAScript 2015, the specification of LabelledStatement did not allow for the association of a statement label with a FunctionDeclaration. However, a labelled FunctionDeclaration was an allowable extension for non-strict code and most browser-hosted ECMAScript implementations supported that extension. In ECMAScript 2015, the grammar productions for LabelledStatement permits use of FunctionDeclaration as a LabelledItem but 13.13.1 includes an Early Error rule that produces a Syntax Error if that occurs. For web browser compatibility, that rule is modified with the addition of the underlined text:

LabelledItem : FunctionDeclaration
  • It is a Syntax Error if any strict mode source code matches this rule.

B.3.3 Block-Level Function Declarations Web Legacy Compatibility Semantics

Prior to ECMAScript 2015, the ECMAScript specification did not define the occurrence of a FunctionDeclaration as an element of a Block statement’s StatementList. However, support for that form of FunctionDeclaration was an allowable extension and most browser-hosted ECMAScript implementations permitted them. Unfortunately, the semantics of such declarations differ among those implementations. Because of these semantic differences, existing web ECMAScript code that uses Block level function declarations is only portable among browser implementation if the usage only depends upon the semantic intersection of all of the browser implementations for such declarations. The following are the use cases that fall within that intersection semantics:

  1. A function is declared and only referenced within a single block
    • A FunctionDeclaration whose BindingIdentifier is the name f occurs exactly once within the function code of an enclosing function g and that declaration is nested within a Block.

    • No other declaration of f that is not a var declaration occurs within the function code of g

    • All occurrences of f as an IdentifierReference are within the StatementList of the Block containing the declaration of f.

  2. A function is declared and possibly used within a single Block but also referenced by an inner function definition that is not contained within that same Block.
    • A FunctionDeclaration whose BindingIdentifier is the name f occurs exactly once within the function code of an enclosing function g and that declaration is nested within a Block.

    • No other declaration of f that is not a var declaration occurs within the function code of g

    • There may be occurrences of f as an IdentifierReference within the StatementList of the Block containing the declaration of f.

    • There is at least one occurrence of f as an IdentifierReference within the function code of g that lexically follows the Block containing the declaration of f.

  3. A function is declared and possibly used within a single block but also referenced within subsequent blocks.
    • A FunctionDeclaration whose BindingIdentifier is the name f occurs exactly once within the function code of an enclosing function g and that declaration is nested within a Block.

    • No other declaration of f that is not a var declaration occurs within the function code of g

    • There may be occurrences of f as an IdentifierReference within the StatementList of the Block containing the declaration of f.

    • There is at least one occurrence of f as an IdentifierReference within another function h that is nested within g and no other declaration of f shadows the references to f from within h.

    • All invocations of h occur after the declaration of f has been evaluated.

The first use case is interoperable with the semantics of Block level function declarations provided by ECMAScript 2015. Any pre-existing ECMAScript code that employees that use case will operate using the Block level function declarations semantics defined by clauses 9, 13, and 14 of this specification.

ECMAScript 2015 interoperability for the second and third use cases requires the following extensions to the clause 9 and clause 14 semantics. During FunctionDeclarationInstantiation (9.2.12) the following steps are performed in place of step 29:

  1. If strict is false, then
    1. For each FunctionDeclaration f in varDeclarations that is directly contained in the StatementList of a Block, CaseClause, or DefaultClause,
      1. Let F be StringValue of the BindingIdentifier of FunctionDeclaration f.
      2. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for func and F is not an element of BoundNames of argumentsList, then
        1. NOTE A var binding for F is only instantiated here if it is neither a VarDeclaredName, the name of a formal parameter, or another FunctionDeclarations.
        2. If instantiatedVarNames does not contain F, then
          1. Let status be varEnvRec.CreateMutableBinding(F).
          2. Assert: status is never an abrupt completion.
          3. Perform varEnvRec.InitializeBinding(F, undefined).
          4. Append F to instantiatedVarNames.
        3. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 14.1.20:
          1. Let fenv be the running execution context’s VariableEnvironment.
          2. Let benv be the running execution context’s LexicalEnvironment.
          3. Let fobj be benv.GetBindingValue(F, false).
          4. ReturnIfAbrupt(fobj).
          5. Let status be fenv.SetMutableBinding(F, fobj, false).
          6. Assert: status is never an abrupt completion.
          7. Return NormalCompletion(empty).

If an ECMAScript implementation has a mechanism for reporting diagnostic warning messages, a warning should be produced for each function whose function code contains a FunctionDeclaration for which steps 1.a.ii.1-3 will be performed.

B.3.4 FunctionDeclarations in IfStatement Statement Clauses

The following rules for IfStatement augment those in 13.6:

IfStatement[Yield, Return] :
if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]

The above rules are only applied when parsing code that is not strict mode code. If any such code is match by one of these rules subsequent processing of that code takes places as if each matching occurrence of FunctionDeclaration[?Yield] was the sole StatementListItem of a BlockStatement occupying that position in the source code. The semantics of such a synthetic BlockStatement includes the web legacy compatibility semantics specified in B.3.3.

B.3.5 VariableStatements in Catch blocks

The content of subclause 13.15.1 is replaced with the following:

Catch : catch ( CatchParameter ) Block
  • It is a Syntax Error if BoundNames of CatchParameter contains any duplicate elements.

  • It is a Syntax Error if any element of the BoundNames of CatchParameter also occurs in the LexicallyDeclaredNames of Block.

  • It is a Syntax Error if any element of the BoundNames of CatchParameter also occurs in the VarDeclaredNames of Block, unless that element is only bound by a VariableStatement or the VariableDeclarationList of a for statement, or the ForBinding of a for-in statement.

NOTE The Block of a Catch clause may contain var declarations that bind a name that is also bound by the CatchParameter. At runtime, such bindings are instantiated in the VariableDeclarationEnvironment. They do not shadow the same-named bindings introduced by the CatchParameter and hence the Initializer for such var declarations will assign to the corresponding catch parameter rather than the var binding. The relaxation of the normal static semantic rule does not apply to names only bound by for-of statements.

This modified behaviour also applies to var and function declarations introduced by direct evals contained within the Block of a Catch clause. This change is accomplished by modify the algorithm of 18.2.1.2 as follows:

Step 5.d.ii.2.a.i is replaced by:

i. If thisEnvRec is not the Environment Record for a Catch clause, throw a SyntaxError exception.

ii. If name is bound by any syntactic form other than a FunctionDeclaration, a VariableStatement, the VariableDeclarationList of a for statement, or the ForBinding of a for-in statement, throw a SyntaxError exception.