# 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.

Some features defined in this annex are specified in this annex, and some are specified in the main body of this document.

When a feature is specified in the main body, each point where it affects the document is marked with the words "Normative Optional" in a coloured box. Moreover, where the feature involves particular wording in an algorithm or early error rule, this is guarded by the condition that “the host supports” the relevant feature. Web browsers are required to support all such features.

Note

This annex describes various legacy features and other characteristics of web browser ECMAScript hosts. 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 define 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 HTML-like Comments

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

## Syntax

InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral HTMLCloseComment Comment :: MultiLineComment SingleLineComment SingleLineHTMLOpenComment SingleLineHTMLCloseComment SingleLineDelimitedComment MultiLineComment :: /* FirstCommentLine opt LineTerminator MultiLineCommentChars opt */ HTMLCloseComment opt FirstCommentLine :: SingleLineDelimitedCommentChars SingleLineHTMLOpenComment :: <!-- SingleLineCommentChars opt SingleLineHTMLCloseComment :: LineTerminatorSequence HTMLCloseComment SingleLineDelimitedComment :: /* SingleLineDelimitedCommentChars opt */ HTMLCloseComment :: WhiteSpaceSequence opt SingleLineDelimitedCommentSequence opt --> SingleLineCommentChars opt SingleLineDelimitedCommentChars :: SingleLineNotAsteriskChar SingleLineDelimitedCommentChars opt * SingleLinePostAsteriskCommentChars opt SingleLineNotAsteriskChar :: SourceCharacter but not one of * or LineTerminator SingleLinePostAsteriskCommentChars :: SingleLineNotForwardSlashOrAsteriskChar SingleLineDelimitedCommentChars opt * SingleLinePostAsteriskCommentChars opt SingleLineNotForwardSlashOrAsteriskChar :: SourceCharacter but not one of / or * or LineTerminator WhiteSpaceSequence :: WhiteSpace WhiteSpaceSequence opt SingleLineDelimitedCommentSequence :: SingleLineDelimitedComment WhiteSpaceSequence opt SingleLineDelimitedCommentSequence opt

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.2 Regular Expressions Patterns

The syntax of 22.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 [UnicodeMode] parameter. However, none of these extensions change the syntax of Unicode patterns recognized when parsing with the [UnicodeMode] parameter present on the goal symbol.

## Syntax

Term[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: [+UnicodeMode] Assertion[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] [+UnicodeMode] Atom[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Quantifier [+UnicodeMode] Atom[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] [~UnicodeMode] QuantifiableAssertion[?NamedCaptureGroups] Quantifier [~UnicodeMode] Assertion[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] [~UnicodeMode] ExtendedAtom[?NamedCaptureGroups] Quantifier [~UnicodeMode] ExtendedAtom[?NamedCaptureGroups] Assertion[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: ^ $ \b \B [+UnicodeMode] (?= Disjunction[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) [+UnicodeMode] (?! Disjunction[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) [~UnicodeMode] QuantifiableAssertion[?NamedCaptureGroups] (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) QuantifiableAssertion[NamedCaptureGroups] :: (?= Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (?! Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) ExtendedAtom[NamedCaptureGroups] :: . \ AtomEscape[~UnicodeMode, ?NamedCaptureGroups] \ [lookahead = c] CharacterClass[~UnicodeMode, ~UnicodeSetsMode] ( GroupSpecifier[~UnicodeMode]opt Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers : Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) InvalidBracedQuantifier ExtendedPatternCharacter InvalidBracedQuantifier :: { DecimalDigits[~Sep] } { DecimalDigits[~Sep] ,} { DecimalDigits[~Sep] , DecimalDigits[~Sep] } ExtendedPatternCharacter :: SourceCharacter but not one of ^ $ \ . * + ? ( ) [ | AtomEscape[UnicodeMode, NamedCaptureGroups] :: [+UnicodeMode] DecimalEscape [~UnicodeMode] DecimalEscape but only if the CapturingGroupNumber of DecimalEscape is ≤ CountLeftCapturingParensWithin(the Pattern containing DecimalEscape) CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode, ?NamedCaptureGroups] [+NamedCaptureGroups] k GroupName[?UnicodeMode] CharacterEscape[UnicodeMode, NamedCaptureGroups] :: ControlEscape c AsciiLetter 0 [lookahead ∉ DecimalDigit] HexEscapeSequence RegExpUnicodeEscapeSequence[?UnicodeMode] [~UnicodeMode] LegacyOctalEscapeSequence IdentityEscape[?UnicodeMode, ?NamedCaptureGroups] IdentityEscape[UnicodeMode, NamedCaptureGroups] :: [+UnicodeMode] SyntaxCharacter [+UnicodeMode] / [~UnicodeMode] SourceCharacterIdentityEscape[?NamedCaptureGroups] SourceCharacterIdentityEscape[NamedCaptureGroups] :: [~NamedCaptureGroups] SourceCharacter but not c [+NamedCaptureGroups] SourceCharacter but not one of c or k ClassAtomNoDash[UnicodeMode, NamedCaptureGroups] :: SourceCharacter but not one of \ or ] or - \ ClassEscape[?UnicodeMode, ?NamedCaptureGroups] \ [lookahead = c] ClassEscape[UnicodeMode, NamedCaptureGroups] :: b [+UnicodeMode] - [~UnicodeMode] c ClassControlLetter CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode, ?NamedCaptureGroups] ClassControlLetter :: DecimalDigit _ Note

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

# B.1.2.1 Static Semantics: Early Errors

The semantics of 22.2.1.1 is extended as follows:

ExtendedAtom :: InvalidBracedQuantifier

- It is a Syntax Error if any source text is matched by this production.

Additionally, the rules for the following productions are modified with the addition of the highlighted text:

NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents

- It is a Syntax Error if IsCharacterClass of the first ClassAtom is true or IsCharacterClass of the second ClassAtom is true and this production has a [UnicodeMode] parameter.
- It is a Syntax Error if IsCharacterClass of the first ClassAtom is false, IsCharacterClass of the second ClassAtom is false, and the CharacterValue of the first ClassAtom is strictly greater than the CharacterValue of the second ClassAtom.

NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents

- It is a Syntax Error if IsCharacterClass of ClassAtomNoDash is true or IsCharacterClass of ClassAtom is true and this production has a [UnicodeMode] parameter.
- It is a Syntax Error if IsCharacterClass of ClassAtomNoDash is false, IsCharacterClass of ClassAtom is false, and the CharacterValue of ClassAtomNoDash is strictly greater than the CharacterValue of ClassAtom.

# B.1.2.2 Static Semantics: CountLeftCapturingParensWithin and CountLeftCapturingParensBefore

In the definitions of CountLeftCapturingParensWithin and CountLeftCapturingParensBefore, references to “ Atom :: ( GroupSpecifier opt Disjunction ) ” are to be interpreted as meaning “ Atom :: ( GroupSpecifier opt Disjunction ) ” or “ ExtendedAtom :: ( GroupSpecifier opt Disjunction ) ”.

# B.1.2.3 Static Semantics: IsCharacterClass

The semantics of 22.2.1.6 is extended as follows:

ClassAtomNoDash :: \ [lookahead = c]

1. Return false.

# B.1.2.4 Static Semantics: CharacterValue

The semantics of 22.2.1.7 is extended as follows:

ClassAtomNoDash :: \ [lookahead = c]

1. Return the numeric value of U+005C (REVERSE SOLIDUS).

ClassEscape :: c ClassControlLetter

1. Let ch be the code point matched by ClassControlLetter.
2. Let i be the numeric value of ch.
3. Return the remainder of dividing i by 32.

CharacterEscape :: LegacyOctalEscapeSequence

1. Return the MV of LegacyOctalEscapeSequence (see 12.9.4.3).

# B.1.2.5 Runtime Semantics: CompileSubpattern

The semantics of CompileSubpattern is extended as follows:

The rule for Term :: QuantifiableAssertion Quantifier is the same as for Term :: Atom Quantifier but with QuantifiableAssertion substituted for Atom.

The rule for Term :: ExtendedAtom Quantifier is the same as for Term :: Atom Quantifier but with ExtendedAtom substituted for Atom.

The rule for Term :: ExtendedAtom is the same as for Term :: Atom but with ExtendedAtom substituted for Atom.

# B.1.2.6 Runtime Semantics: CompileAssertion

CompileAssertion rules for the Assertion :: (?= Disjunction ) and Assertion :: (?! Disjunction ) productions are also used for the QuantifiableAssertion productions, but with QuantifiableAssertion substituted for Assertion.

# B.1.2.7 Runtime Semantics: CompileAtom

CompileAtom rules for the Atom productions except for Atom :: PatternCharacter are also used for the ExtendedAtom productions, but with ExtendedAtom substituted for Atom. The following rules, with parameter direction, are also added:

ExtendedAtom :: \ [lookahead = c]

1. Let A be the CharSet containing the single character `\` U+005C (REVERSE SOLIDUS).
2. Return CharacterSetMatcher(rer, A, false, direction).

ExtendedAtom :: ExtendedPatternCharacter

1. Let ch be the character represented by ExtendedPatternCharacter.
2. Let A be a one-element CharSet containing the character ch.
3. Return CharacterSetMatcher(rer, A, false, direction).

# B.1.2.8 Runtime Semantics: CompileToCharSet

The semantics of 22.2.2.9 is extended as follows:

The following two rules replace the corresponding rules of CompileToCharSet.

NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents

1. Let A be CompileToCharSet of the first ClassAtom with argument rer.
2. Let B be CompileToCharSet of the second ClassAtom with argument rer.
3. Let C be CompileToCharSet of ClassContents with argument rer.
4. Let D be CharacterRangeOrUnion(rer, A, B).
5. Return the union of D and C.

NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents

1. Let A be CompileToCharSet of ClassAtomNoDash with argument rer.
2. Let B be CompileToCharSet of ClassAtom with argument rer.
3. Let C be CompileToCharSet of ClassContents with argument rer.
4. Let D be CharacterRangeOrUnion(rer, A, B).
5. Return the union of D and C.

In addition, the following rules are added to CompileToCharSet.

ClassEscape :: c ClassControlLetter

1. Let cv be the CharacterValue of this ClassEscape.
2. Let c be the character whose character value is cv.
3. Return the CharSet containing the single character c.

ClassAtomNoDash :: \ [lookahead = c]

1. Return the CharSet containing the single character `\` U+005C (REVERSE SOLIDUS).

Note
This production can only be reached from the sequence `\c` within a character class where it is not followed by an acceptable control character.

# B.1.2.8.1 CharacterRangeOrUnion ( rer, A, B )

The abstract operation CharacterRangeOrUnion takes arguments rer (a RegExp Record), A (a CharSet), and B (a CharSet) and returns a CharSet. It performs the following steps when called:

1. If HasEitherUnicodeFlag(rer) is false, then
   1. If A does not contain exactly one character or B does not contain exactly one character, then
      1. Let C be the CharSet containing the single character `-` U+002D (HYPHEN-MINUS).
      2. Return the union of CharSets A, B and C.
2. Return CharacterRange(A, B).

# B.1.2.9 Static Semantics: ParsePattern ( patternText, u, v )

The semantics of 22.2.3.4 is extended as follows:

The abstract operation ParsePattern takes arguments patternText (a sequence of Unicode code points), u (a Boolean), and v (a Boolean). It performs the following steps when called:

1. If v is true and u is true, then
   1. Let parseResult be a List containing one or more SyntaxError objects.
2. Else if v is true, then
   1. Let parseResult be ParseText(patternText, Pattern[+UnicodeMode, +UnicodeSetsMode, +NamedCaptureGroups]).
3. Else if u is true, then
   1. Let parseResult be ParseText(patternText, Pattern[+UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups]).
4. Else,
   1. Let parseResult be ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, ~NamedCaptureGroups]).
   2. If parseResult is a Parse Node and parseResult contains a GroupName, then
      1. Set parseResult to ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups]).
5. Return parseResult.

# 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 97 are added to Table 6.

Table 97: 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 )

This 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.

When replacing a code unit of numeric value less than or equal to 0x00FF, a two-digit escape sequence of the form `%xx` is used. When replacing a code unit of numeric value strictly greater than 0x00FF, a four-digit escape sequence of the form `%uxxxx` is used.

It is the %escape% intrinsic object.

It performs the following steps when called:

1. Set string to ? ToString(string).
2. Let len be the length of string.
3. Let R be the empty String.
4. Let unescapedSet be the string-concatenation of the ASCII word characters and "@*+-./".
5. Let k be 0.
6. Repeat, while k < len,
   1. Let C be the code unit at index k within string.
   2. If unescapedSet contains C, then
      1. Let S be C.
   3. Else,
      1. Let n be the numeric value of C.
      2. If n < 256, then
         1. Let hex be the String representation of n, formatted as an uppercase hexadecimal number.
         2. Let S be the string-concatenation of "%" and StringPad(hex, 2, "0", start).
      3. Else,
         1. Let hex be the String representation of n, formatted as an uppercase hexadecimal number.
         2. Let S be the string-concatenation of "%u" and StringPad(hex, 4, "0", start).
   4. Set R to the string-concatenation of R and S.
   5. Set k to k + 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 )

This 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.

It is the %unescape% intrinsic object.

It performs the following steps when called:

1. Set string to ? ToString(string).
2. Let len be the length of string.
3. Let R be the empty String.
4. Let k be 0.
5. Repeat, while k < len,
   1. Let C be the code unit at index k within string.
   2. If C is the code unit 0x0025 (PERCENT SIGN), then
      1. Let hexDigits be the empty String.
      2. Let optionalAdvance be 0.
      3. If k + 5 < len and the code unit at index k + 1 within string is the code unit 0x0075 (LATIN SMALL LETTER U), then
         1. Set hexDigits to the substring of string from k + 2 to k + 6.
         2. Set optionalAdvance to 5.
      4. Else if k + 3 ≤ len, then
         1. Set hexDigits to the substring of string from k + 1 to k + 3.
         2. Set optionalAdvance to 2.
      5. Let parseResult be ParseText(hexDigits, HexDigits[~Sep]).
      6. If parseResult is a Parse Node, then
         1. Let n be the MV of parseResult.
         2. Set C to the code unit whose numeric value is n.
         3. Set k to k + optionalAdvance.
   3. Set R to the string-concatenation of R and C.
   4. Set k to k + 1.
6. Return R.

# B.2.2 Additional Properties of the String.prototype Object

# B.2.2.1 String.prototype.substr ( start, length )

This method returns a substring of the result of converting the this value 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.

It performs the following steps when called:

1. Let O be the this value.
2. Perform ? RequireObjectCoercible(O).
3. Let S be ? ToString(O).
4. Let size be the length of S.
5. Let intStart be ? ToIntegerOrInfinity(start).
6. If intStart = -∞, set intStart to 0.
7. Else if intStart < 0, set intStart to max(size + intStart, 0).
8. Else, set intStart to min(intStart, size).
9. If length is undefined, let intLength be size; else let intLength be ? ToIntegerOrInfinity(length).
10. Set intLength to the result of clamping intLength between 0 and size.
11. Let intEnd be min(intStart + intLength, size).
12. Return the substring of S from intStart to intEnd.

Note

This method 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.2.2 String.prototype.anchor ( name )

This method performs the following steps when called:

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

# B.2.2.2.1 CreateHTML ( string, tag, attribute, value )

The abstract operation CreateHTML takes arguments string (an ECMAScript language value), tag (a String), attribute (a String), and value (an ECMAScript language value) and returns either a normal completion containing a String or a throw completion. It performs the following steps when called:

1. Perform ? RequireObjectCoercible(string).
2. Let S be ? ToString(string).
3. Let p1 be the string-concatenation of "<" and tag.
4. If attribute is not the empty String, then
   1. Let V be ? ToString(value).
   2. 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;".
   3. Set p1 to the string-concatenation of:
      - p1
      - the code unit 0x0020 (SPACE)
      - attribute
      - the code unit 0x003D (EQUALS SIGN)
      - the code unit 0x0022 (QUOTATION MARK)
      - escapedV
      - the code unit 0x0022 (QUOTATION MARK)
5. Let p2 be the string-concatenation of p1 and ">".
6. Let p3 be the string-concatenation of p2 and S.
7. Let p4 be the string-concatenation of p3, "</", tag, and ">".
8. Return p4.

# B.2.2.3 String.prototype.big ( )

This method performs the following steps when called:

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

# B.2.2.4 String.prototype.blink ( )

This method performs the following steps when called:

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

# B.2.2.5 String.prototype.bold ( )

This method performs the following steps when called:

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

# B.2.2.6 String.prototype.fixed ( )

This method performs the following steps when called:

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

# B.2.2.7 String.prototype.fontcolor ( colour )

This method performs the following steps when called:

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

# B.2.2.8 String.prototype.fontsize ( size )

This method performs the following steps when called:

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

# B.2.2.9 String.prototype.italics ( )

This method performs the following steps when called:

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

# B.2.2.10 String.prototype.link ( url )

This method performs the following steps when called:

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

# B.2.2.11 String.prototype.small ( )

This method performs the following steps when called:

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

# B.2.2.12 String.prototype.strike ( )

This method performs the following steps when called:

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

# B.2.2.13 String.prototype.sub ( )

This method performs the following steps when called:

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

# B.2.2.14 String.prototype.sup ( )

This method performs the following steps when called:

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

# B.2.2.15 String.prototype.trimLeft ( )

Note

The property "trimStart" is preferred. The "trimLeft" property is provided principally for compatibility with old code. It is recommended that the "trimStart" property be used in new ECMAScript code.

The initial value of the "trimLeft" property is %String.prototype.trimStart%, defined in 22.1.3.34.

# B.2.2.16 String.prototype.trimRight ( )

Note

The property "trimEnd" is preferred. The "trimRight" property is provided principally for compatibility with old code. It is recommended that the "trimEnd" property be used in new ECMAScript code.

The initial value of the "trimRight" property is %String.prototype.trimEnd%, defined in 22.1.3.33.

# B.2.3 Additional Properties of the Date.prototype Object

# B.2.3.1 Date.prototype.getYear ( )

Note

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

This method performs the following steps when called:

1. Let dateObject be the this value.
2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
3. Let t be dateObject.[[DateValue]].
4. If t is NaN, return NaN.
5. Return YearFromTime(LocalTime(t)) - 1900𝔽.

# B.2.3.2 Date.prototype.setYear ( year )

Note

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

This method performs the following steps when called:

1. Let dateObject be the this value.
2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
3. Let t be dateObject.[[DateValue]].
4. Let y be ? ToNumber(year).
5. If t is NaN, set t to +0𝔽; else set t to LocalTime(t).
6. Let yyyy be MakeFullYear(y).
7. Let d be MakeDay(yyyy, MonthFromTime(t), DateFromTime(t)).
8. Let date be MakeDate(d, TimeWithinDay(t)).
9. Let u be TimeClip(UTC(date)).
10. Set dateObject.[[DateValue]] to u.
11. Return u.

# B.2.3.3 Date.prototype.toGMTString ( )

Note

The `toUTCString` method is preferred. This method is provided principally for compatibility with old code.

The initial value of the "toGMTString" property is %Date.prototype.toUTCString%, defined in 21.4.4.43.

# B.2.4 Additional Properties of the RegExp.prototype Object

# B.2.4.1 RegExp.prototype.compile ( pattern, flags )

This method performs the following steps when called:

1. Let O be the this value.
2. Perform ? RequireInternalSlot(O, [[RegExpMatcher]]).
3. If pattern is an Object and pattern has a [[RegExpMatcher]] internal slot, then
   1. If flags is not undefined, throw a TypeError exception.
   2. Let P be pattern.[[OriginalSource]].
   3. Let F be pattern.[[OriginalFlags]].
4. Else,
   1. Let P be pattern.
   2. Let F be flags.
5. Return ? RegExpInitialize(O, P, F).

Note

This method completely reinitializes the this value 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 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 and later, the grammar production for LabelledStatement permits use of FunctionDeclaration as a LabelledItem but 14.13.1 includes an Early Error rule that produces a Syntax Error if that occurs. That rule is then modified to suppress the Syntax Error in non-strict code if the host supports this feature.

Note

The early error rules for WithStatement, IfStatement, and IterationStatement prevent these statements from containing a labelled FunctionDeclaration in non-strict code.

# B.3.2 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 source text that uses Block level function declarations is only portable among browser implementations 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.

   - One or more FunctionDeclarations whose BindingIdentifier is the name f occur 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.

   - One or more FunctionDeclarations whose BindingIdentifier is the name f occur 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.

3. A function is declared and possibly used within a single block but also referenced within subsequent blocks.

   - One or more FunctionDeclaration whose BindingIdentifier is the name f occur 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.

The first use case is interoperable with the semantics of Block level function declarations provided by ECMAScript 2015. Any pre-existing ECMAScript source text that employs that use case will operate using the Block level function declarations semantics defined by clauses 10, 14, and 15.

ECMAScript 2015 interoperability for the second and third use cases requires the following extensions to the clause 10, clause 15, clause 19.2.1 and clause 16.1.7 semantics.

If an ECMAScript implementation has a mechanism for reporting diagnostic warning messages, a warning should be produced when code contains a FunctionDeclaration for which these compatibility semantics are applied and introduce observable differences from non-compatibility semantics. For example, if a var binding is not introduced because its introduction would create an early error, a warning message should not be produced.

This feature involves special semantics at the following points:

- one of the early error rules for Block : { StatementList } in 14.2.1
- one of the early error rules for SwitchStatement : switch ( Expression ) CaseBlock in 14.12.1
- step 32.a in FunctionDeclarationInstantiation
- step 3.a.ii.1 in BlockDeclarationInstantiation
- step 3.b.iii in BlockDeclarationInstantiation
- step 12 in GlobalDeclarationInstantiation
- step 13 in EvalDeclarationInstantiation

# B.3.3 FunctionDeclarations in IfStatement Statement Clauses

The following augments the IfStatement production in 14.6:

IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else FunctionDeclaration[?Yield, ?Await, ~Default] if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else FunctionDeclaration[?Yield, ?Await, ~Default] if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] [lookahead ≠ else]

This production only applies when parsing non-strict code. Source text matched by this production is processed as if each matching occurrence of FunctionDeclaration[?Yield, ?Await, ~Default] was the sole StatementListItem of a BlockStatement occupying that position in the source text. The semantics of such a synthetic BlockStatement includes the web legacy compatibility semantics specified in B.3.2.

# B.3.4 VariableStatements in Catch Blocks

In this feature, the Block of a Catch clause may contain `var` declarations that bind a name that is also bound by the CatchParameter. This is accomplished by modifying an early error rule for Catch : catch ( CatchParameter ) Block in 14.15.1.

Note

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.

This modified behaviour also applies to `var` and `function` declarations introduced by direct eval calls contained within the Block of a Catch clause. This change is accomplished by modifying steps 3.d.i.2.a.i and 13.b.ii.4.a.i.i in EvalDeclarationInstantiation.

# B.3.5 Initializers in ForIn Statement Heads

The following augments the ForInOfStatement production in 14.7.5:

ForInOfStatement[Yield, Await, Return] : for ( var BindingIdentifier[?Yield, ?Await] Initializer[~In, ?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]

This production only applies when parsing non-strict code.

The static semantics of ContainsDuplicateLabels in 8.3.1 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement

1. Return ContainsDuplicateLabels of Statement with argument labelSet.

The static semantics of ContainsUndefinedBreakTarget in 8.3.2 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement

1. Return ContainsUndefinedBreakTarget of Statement with argument labelSet.

The static semantics of ContainsUndefinedContinueTarget in 8.3.3 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement

1. Return ContainsUndefinedContinueTarget of Statement with arguments iterationSet and « ».

The static semantics of IsDestructuring in 14.7.5.2 are augmented with the following:

BindingIdentifier : Identifier yield await

1. Return false.

The static semantics of VarDeclaredNames in 8.2.6 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement

1. Let names1 be the BoundNames of BindingIdentifier.
2. Let names2 be the VarDeclaredNames of Statement.
3. Return the list-concatenation of names1 and names2.

The static semantics of VarScopedDeclarations in 8.2.7 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement

1. Let declarations1 be « BindingIdentifier ».
2. Let declarations2 be the VarScopedDeclarations of Statement.
3. Return the list-concatenation of declarations1 and declarations2.

The runtime semantics of ForInOfLoopEvaluation in 14.7.5.5 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement

1. Let bindingId be the StringValue of BindingIdentifier.
2. Let lhs be ? ResolveBinding(bindingId).
3. If IsAnonymousFunctionDefinition(Initializer) is true, then
   1. Let value be ? NamedEvaluation of Initializer with argument bindingId.
4. Else,
   1. Let rhs be ? Evaluation of Initializer.
   2. Let value be ? GetValue(rhs).
5. Perform ? PutValue(lhs, value).
6. Let keyResult be ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
7. Return ? ForIn/OfBodyEvaluation(BindingIdentifier, Statement, keyResult, enumerate, var-binding, labelSet).

# B.3.6 The [[IsHTMLDDA]] Internal Slot

An [[IsHTMLDDA]] internal slot may exist on host-defined objects. Objects with an [[IsHTMLDDA]] internal slot behave like undefined in the ToBoolean and IsLooselyEqual abstract operations and when used as an operand for the `typeof` operator.

Note

Objects with an [[IsHTMLDDA]] internal slot are never created by this specification. However, the `document.all` object in web browsers is a host-defined exotic object with this slot that exists for web compatibility purposes. There are no other known examples of this type of object and implementations should not create any with the exception of `document.all`.

This feature involves special semantics at the following points:

- step 3 in ToBoolean
- step 4 in IsLooselyEqual
- step 12 in the evaluation semantics for `typeof`

# B.3.7 Non-default behaviour in HostMakeJobCallback

The HostMakeJobCallback abstract operation allows hosts which are web browsers to specify non-default behaviour.

# B.3.8 Non-default behaviour in HostEnsureCanAddPrivateElement

The HostEnsureCanAddPrivateElement abstract operation allows hosts which are web browsers to specify non-default behaviour.

# B.3.9 Runtime Errors for Function Call Assignment Targets

When a function call (13.3.6) is used as an assignment target in non-strict code, instead of producing an early error, a ReferenceError exception is thrown during evaluation of the assignment.

Note

When the assignment target is the LeftHandSideExpression of an AssignmentExpression, the assignment operator must be `=` or an AssignmentOperator; in particular, the allowance here does not apply to the logical assignment operators (`??=`, `&&=`, `||=`).

See step 1 of AssignmentTargetType for CallExpression : CoverCallExpressionAndAsyncArrowHead and CallExpression : CallExpression Arguments .