12 ECMAScript Language: Expressions

12.1 Identifiers

Syntax

IdentifierReference[Yield] :
Identifier
[~Yield] yield
BindingIdentifier[Yield] :
Identifier
[~Yield] yield
LabelIdentifier[Yield] :
Identifier
[~Yield] yield
Identifier :
IdentifierName but not ReservedWord

12.1.1 Static Semantics: Early Errors

BindingIdentifier : Identifier
  • It is a Syntax Error if the code matched by this production is contained in strict mode code and the StringValue of Identifier is "arguments" or "eval".

IdentifierReference : yield
BindingIdentifier : yield
LabelIdentifier : yield

  • It is a Syntax Error if the code matched by this production is contained in strict mode code.

IdentifierReference[Yield] : Identifier
BindingIdentifier[Yield] : Identifier
LabelIdentifier[Yield] : Identifier

  • It is a Syntax Error if this production has a [Yield] parameter and StringValue of Identifier is "yield".

Identifier : IdentifierName but not ReservedWord
  • It is a Syntax Error if this phrase is contained in strict mode code and the StringValue of IdentifierName is: "implements", "interface", "let", "package", "private", "protected", "public", "static", or "yield".

  • It is a Syntax Error if StringValue of IdentifierName is the same String value as the StringValue of any ReservedWord except for yield.

NOTE StringValue of IdentifierName normalizes any Unicode escape sequences in IdentifierName hence such escapes cannot be used to write an Identifier whose code point sequence is the same as a ReservedWord.

12.1.2 Static Semantics: BoundNames

See also: 13.3.1.2, 13.3.2.1, 13.3.3.1, 13.7.5.2, 14.1.3, 14.2.2, 14.4.2, 14.5.2, 15.2.2.2, 15.2.3.2.

BindingIdentifier : Identifier
  1. Return a new List containing the StringValue of Identifier.
BindingIdentifier : yield
  1. Return a new List containing "yield".

12.1.3 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

IdentifierReference : Identifier
  1. If this IdentifierReference is contained in strict mode code and StringValue of Identifier is "eval" or "arguments", return false.
  2. Return true.
IdentifierReference : yield
  1. Return true.

12.1.4 Static Semantics: StringValue

See also: 11.6.1.2, 11.8.4.2.

IdentifierReference : yield
BindingIdentifier : yield
LabelIdentifier : yield

  1. Return "yield".
Identifier : IdentifierName but not ReservedWord
  1. Return the StringValue of IdentifierName.

12.1.5 Runtime Semantics: BindingInitialization

With arguments value and environment.

See also: 13.3.3.5, 13.7.5.9.

NOTE undefined is passed for environment to indicate that a PutValue operation should be used to assign the initialization value. This is the case for var statements and formal parameter lists of some non-strict functions (See 9.2.12). In those cases a lexical binding is hoisted and preinitialized prior to evaluation of its initializer.

BindingIdentifier : Identifier
  1. Let name be StringValue of Identifier.
  2. Return InitializeBoundName( name, value, environment).
BindingIdentifier : yield
  1. Return InitializeBoundName("yield", value, environment).

12.1.5.1 Runtime Semantics: InitializeBoundName(name, value, environment)

  1. Assert: Type(name) is String.
  2. If environment is not undefined, then
    1. Let env be the EnvironmentRecord component of environment.
    2. Perform env.InitializeBinding(name, value).
    3. Return NormalCompletion(undefined).
  3. Else
    1. Let lhs be ResolveBinding(name).
    2. Return PutValue(lhs, value).

12.1.6 Runtime Semantics: Evaluation

IdentifierReference : Identifier
  1. Return ResolveBinding(StringValue of Identifier).
IdentifierReference : yield
  1. Return ResolveBinding("yield").

NOTE 1 The result of evaluating an IdentifierReference is always a value of type Reference.

NOTE 2 In non-strict code, the keyword yield may be used as an identifier. Evaluating the IdentifierReference production resolves the binding of yield as if it was an Identifier. Early Error restriction ensures that such an evaluation only can occur for non-strict code. See 13.3.1 for the handling of yield in binding creation contexts.

12.2 Primary Expression

Syntax

PrimaryExpression[Yield] :
this
IdentifierReference[?Yield]
Literal
ArrayLiteral[?Yield]
ObjectLiteral[?Yield]
FunctionExpression
ClassExpression[?Yield]
GeneratorExpression
RegularExpressionLiteral
TemplateLiteral[?Yield]
CoverParenthesizedExpressionAndArrowParameterList[?Yield]
CoverParenthesizedExpressionAndArrowParameterList[Yield] :
( Expression[In, ?Yield] )
( )
( ... BindingIdentifier[?Yield] )
( Expression[In, ?Yield] , ... BindingIdentifier[?Yield] )

Supplemental Syntax

When processing the production

      PrimaryExpression[Yield] : CoverParenthesizedExpressionAndArrowParameterList[?Yield]

the interpretation of CoverParenthesizedExpressionAndArrowParameterList is refined using the following grammar:

ParenthesizedExpression[Yield] :
( Expression[In, ?Yield] )

12.2.1 Semantics

12.2.1.1 Static Semantics: CoveredParenthesizedExpression

CoverParenthesizedExpressionAndArrowParameterList[Yield] : ( Expression[In, ?Yield] )
  1. Return the result of parsing the lexical token stream matched by CoverParenthesizedExpressionAndArrowParameterList[Yield] using either ParenthesizedExpression or ParenthesizedExpression[Yield] as the goal symbol depending upon whether the [Yield] grammar parameter was present when CoverParenthesizedExpressionAndArrowParameterList was matched.

12.2.1.2 Static Semantics: HasName

See also: 14.1.8, 14.2.7, 14.4.7, 14.5.6.

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. If IsFunctionDefinition of expr is false, return false.
  3. Return HasName of expr.

12.2.1.3 Static Semantics: IsFunctionDefinition

See also: 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

PrimaryExpression :
this
IdentifierReference
Literal
ArrayLiteral
ObjectLiteral
RegularExpressionLiteral
TemplateLiteral
  1. Return false.
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return IsFunctionDefinition of expr.

12.2.1.4 Static Semantics: IsIdentifierRef

See also: 12.3.1.4.

PrimaryExpression : IdentifierReference
  1. Return true.
PrimaryExpression :
this
Literal
ArrayLiteral
ObjectLiteral
FunctionExpression
ClassExpression
GeneratorExpression
RegularExpressionLiteral
TemplateLiteral
CoverParenthesizedExpressionAndArrowParameterList
  1. Return false.

12.2.1.5 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

PrimaryExpression :
this
Literal
ArrayLiteral
ObjectLiteral
FunctionExpression
ClassExpression
GeneratorExpression
RegularExpressionLiteral
TemplateLiteral
  1. Return false.
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return IsValidSimpleAssignmentTarget of expr.

12.2.2 The this Keyword

12.2.2.1 Runtime Semantics: Evaluation

PrimaryExpression : this
  1. Return ResolveThisBinding( ) .

12.2.3 Identifier Reference

See 12.1 for IdentifierReference.

12.2.4 Literals

Syntax

Literal :
NullLiteral
BooleanLiteral
NumericLiteral
StringLiteral

12.2.4.1 Runtime Semantics: Evaluation

Literal : NullLiteral
  1. Return null.
Literal : BooleanLiteral
  1. Return false if BooleanLiteral is the token false.
  2. Return true if BooleanLiteral is the token true.
Literal : NumericLiteral
  1. Return the number whose value is MV of NumericLiteral as defined in 11.8.3.
Literal : StringLiteral
  1. Return the StringValue of StringLiteral as defined in 11.8.4.2.

12.2.5 Array Initializer

NOTE An ArrayLiteral is an expression describing the initialization of an Array object, using a list, of zero or more expressions each of which represents an array element, enclosed in square brackets. The elements need not be literals; they are evaluated each time the array initializer is evaluated.

Array elements may be elided at the beginning, middle or end of the element list. Whenever a comma in the element list is not preceded by an AssignmentExpression (i.e., a comma at the beginning or after another comma), the missing array element contributes to the length of the Array and increases the index of subsequent elements. Elided array elements are not defined. If an element is elided at the end of an array, that element does not contribute to the length of the Array.

Syntax

ArrayLiteral[Yield] :
[ Elisionopt ]
[ ElementList[?Yield] ]
[ ElementList[?Yield] , Elisionopt ]
ElementList[Yield] :
Elisionopt AssignmentExpression[In, ?Yield]
Elisionopt SpreadElement[?Yield]
ElementList[?Yield] , Elisionopt AssignmentExpression[In, ?Yield]
ElementList[?Yield] , Elisionopt SpreadElement[?Yield]
Elision :
,
Elision ,
SpreadElement[Yield] :
... AssignmentExpression[In, ?Yield]

12.2.5.1 Static Semantics: ElisionWidth

Elision : ,
  1. Return the numeric value 1.
Elision : Elision ,
  1. Let preceding be the ElisionWidth of Elision.
  2. Return preceding+1.

12.2.5.2 Runtime Semantics: ArrayAccumulation

With parameters array and nextIndex.

ElementList : Elisionopt AssignmentExpression
  1. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  2. Let initResult be the result of evaluating AssignmentExpression.
  3. Let initValue be GetValue(initResult).
  4. ReturnIfAbrupt(initValue).
  5. Let created be CreateDataProperty(array, ToString(ToUint32(nextIndex+padding)), initValue).
  6. Assert: created is true.
  7. Return nextIndex+padding+1.
ElementList : Elisionopt SpreadElement
  1. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  2. Return the result of performing ArrayAccumulation for SpreadElement with arguments array and nextIndex+padding.
ElementList : ElementList , Elisionopt AssignmentExpression
  1. Let postIndex be the result of performing ArrayAccumulation for ElementList with arguments array and nextIndex.
  2. ReturnIfAbrupt(postIndex).
  3. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  4. Let initResult be the result of evaluating AssignmentExpression.
  5. Let initValue be GetValue(initResult).
  6. ReturnIfAbrupt(initValue).
  7. Let created be CreateDataProperty(array, ToString(ToUint32(postIndex+padding)), initValue).
  8. Assert: created is true.
  9. Return postIndex+padding+1.
ElementList : ElementList , Elisionopt SpreadElement
  1. Let postIndex be the result of performing ArrayAccumulation for ElementList with arguments array and nextIndex.
  2. ReturnIfAbrupt(postIndex).
  3. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  4. Return the result of performing ArrayAccumulation for SpreadElement with arguments array and postIndex+padding.
SpreadElement : ... AssignmentExpression
  1. Let spreadRef be the result of evaluating AssignmentExpression.
  2. Let spreadObj be GetValue(spreadRef).
  3. Let iterator be GetIterator(spreadObj).
  4. ReturnIfAbrupt(iterator).
  5. Repeat
    1. Let next be IteratorStep(iterator).
    2. ReturnIfAbrupt(next).
    3. If next is false, return nextIndex.
    4. Let nextValue be IteratorValue(next).
    5. ReturnIfAbrupt(nextValue).
    6. Let status be CreateDataProperty(array, ToString(nextIndex), nextValue).
    7. Assert: status is true .
    8. Let nextIndex be nextIndex + 1.

NOTE CreateDataProperty is used to ensure that own properties are defined for the array even if the standard built-in Array prototype object has been modified in a manner that would preclude the creation of new own properties using [[Set]].

12.2.5.3 Runtime Semantics: Evaluation

ArrayLiteral : [ Elisionopt ]
  1. Let array be ArrayCreate(0).
  2. Let pad be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  3. Perform Set(array, "length", pad, false).
  4. NOTE: The above Set cannot fail because of the nature of the object returned by ArrayCreate.
  5. Return array.
ArrayLiteral : [ ElementList ]
  1. Let array be ArrayCreate(0).
  2. Let len be the result of performing ArrayAccumulation for ElementList with arguments array and 0.
  3. ReturnIfAbrupt(len).
  4. Perform Set(array, "length", len, false).
  5. NOTE: The above Set cannot fail because of the nature of the object returned by ArrayCreate.
  6. Return array.
ArrayLiteral : [ ElementList , Elisionopt ]
  1. Let array be ArrayCreate(0).
  2. Let len be the result of performing ArrayAccumulation for ElementList with arguments array and 0.
  3. ReturnIfAbrupt(len).
  4. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
  5. Perform Set(array, "length", ToUint32(padding+len), false).
  6. NOTE: The above Set cannot fail because of the nature of the object returned by ArrayCreate.
  7. Return array.

12.2.6 Object Initializer

NOTE 1 An object initializer is an expression describing the initialization of an Object, written in a form resembling a literal. It is a list of zero or more pairs of property keys and associated values, enclosed in curly brackets. The values need not be literals; they are evaluated each time the object initializer is evaluated.

Syntax

ObjectLiteral[Yield] :
{ }
{ PropertyDefinitionList[?Yield] }
{ PropertyDefinitionList[?Yield] , }
PropertyDefinitionList[Yield] :
PropertyDefinition[?Yield]
PropertyDefinitionList[?Yield] , PropertyDefinition[?Yield]
PropertyDefinition[Yield] :
IdentifierReference[?Yield]
CoverInitializedName[?Yield]
PropertyName[?Yield] : AssignmentExpression[In, ?Yield]
MethodDefinition[?Yield]
PropertyName[Yield] :
LiteralPropertyName
ComputedPropertyName[?Yield]
LiteralPropertyName :
IdentifierName
StringLiteral
NumericLiteral
ComputedPropertyName[Yield] :
[ AssignmentExpression[In, ?Yield] ]
CoverInitializedName[Yield] :
IdentifierReference[?Yield] Initializer[In, ?Yield]
Initializer[In, Yield] :
= AssignmentExpression[?In, ?Yield]

NOTE 2 MethodDefinition is defined in 14.3.

NOTE 3 In certain contexts, ObjectLiteral is used as a cover grammar for a more restricted secondary grammar. The CoverInitializedName production is necessary to fully cover these secondary grammars. However, use of this production results in an early Syntax Error in normal contexts where an actual ObjectLiteral is expected.

12.2.6.1 Static Semantics: Early Errors

PropertyDefinition : MethodDefinition
  • It is a Syntax Error if HasDirectSuper of MethodDefinition is true.

In addition to describing an actual object initializer the ObjectLiteral productions are also used as a cover grammar for ObjectAssignmentPattern (12.14.5). and may be recognized as part of a CoverParenthesizedExpressionAndArrowParameterList. When ObjectLiteral appears in a context where ObjectAssignmentPattern is required the following Early Error rules are not applied. In addition, they are not applied when initially parsing a CoverParenthesizedExpressionAndArrowParameterList.

PropertyDefinition : CoverInitializedName
  • Always throw a Syntax Error if code matches this production.

NOTE This production exists so that ObjectLiteral can serve as a cover grammar for ObjectAssignmentPattern (12.14.5). It cannot occur in an actual object initializer.

12.2.6.2 Static Semantics: ComputedPropertyContains

With parameter symbol.

See also: 14.3.2, 14.4.3, 14.5.5.

PropertyName : LiteralPropertyName
  1. Return false.
PropertyName : ComputedPropertyName
  1. Return the result of ComputedPropertyName Contains symbol.

12.2.6.3 Static Semantics: Contains

With parameter symbol.

See also: 5.3, 12.3.1.1, 14.1.4, 14.2.3, 14.4.4, 14.5.4.

PropertyDefinition : MethodDefinition
  1. If symbol is MethodDefinition, return true.
  2. Return the result of ComputedPropertyContains for MethodDefinition with argument symbol.

NOTE Static semantic rules that depend upon substructure generally do not look into function definitions.

LiteralPropertyName : IdentifierName
  1. If symbol is a ReservedWord, return false.
  2. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true;
  3. Return false.

12.2.6.4 Static Semantics: HasComputedPropertyKey

See also: 14.3.4, 14.4.5

PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. If HasComputedPropertyKey of PropertyDefinitionList is true, return true.
  2. Return HasComputedPropertyKey of PropertyDefinition.
PropertyDefinition : IdentifierReference
  1. Return false.
PropertyDefinition : PropertyName : AssignmentExpression
  1. Return IsComputedPropertyKey of PropertyName.

12.2.6.5 Static Semantics: IsComputedPropertyKey

PropertyName : LiteralPropertyName
  1. Return false.
PropertyName : ComputedPropertyName
  1. Return true.

12.2.6.6 Static Semantics: PropName

See also: 14.3.6, 14.4.10, 14.5.12

PropertyDefinition : IdentifierReference
  1. Return StringValue of IdentifierReference.
PropertyDefinition : PropertyName : AssignmentExpression
  1. Return PropName of PropertyName.
LiteralPropertyName : IdentifierName
  1. Return StringValue of IdentifierName.
LiteralPropertyName : StringLiteral
  1. Return a String value whose code units are the SV of the StringLiteral.
LiteralPropertyName : NumericLiteral
  1. Let nbr be the result of forming the value of the NumericLiteral.
  2. Return ToString(nbr).
ComputedPropertyName : [ AssignmentExpression ]
  1. Return empty.

12.2.6.7 Static Semantics: PropertyNameList

PropertyDefinitionList : PropertyDefinition
  1. If PropName of PropertyDefinition is empty, return a new empty List.
  2. Return a new List containing PropName of PropertyDefinition.
PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. Let list be PropertyNameList of PropertyDefinitionList.
  2. If PropName of PropertyDefinition is empty, return list.
  3. Append PropName of PropertyDefinition to the end of list.
  4. Return list.

12.2.6.8 Runtime Semantics: Evaluation

ObjectLiteral : { }
  1. Return ObjectCreate(%ObjectPrototype%).
ObjectLiteral :
{ PropertyDefinitionList }
{ PropertyDefinitionList , }
  1. Let obj be ObjectCreate(%ObjectPrototype%).
  2. Let status be the result of performing PropertyDefinitionEvaluation of PropertyDefinitionList with arguments obj and true.
  3. ReturnIfAbrupt(status).
  4. Return obj.
LiteralPropertyName : IdentifierName
  1. Return StringValue of IdentifierName.
LiteralPropertyName : StringLiteral
  1. Return a String value whose code units are the SV of the StringLiteral.
LiteralPropertyName : NumericLiteral
  1. Let nbr be the result of forming the value of the NumericLiteral.
  2. Return ToString(nbr).
ComputedPropertyName : [ AssignmentExpression ]
  1. Let exprValue be the result of evaluating AssignmentExpression.
  2. Let propName be GetValue(exprValue).
  3. ReturnIfAbrupt(propName).
  4. Return ToPropertyKey(propName).

12.2.6.9 Runtime Semantics: PropertyDefinitionEvaluation

With parameter object and enumerable.

See also: 14.3.9, 14.4.13, B.3.1

PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. Let status be the result of performing PropertyDefinitionEvaluation of PropertyDefinitionList with arguments object and enumerable.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing PropertyDefinitionEvaluation of PropertyDefinition with arguments object and enumerable.
PropertyDefinition : IdentifierReference
  1. Let propName be StringValue of IdentifierReference.
  2. Let exprValue be the result of evaluating IdentifierReference.
  3. ReturnIfAbrupt(exprValue).
  4. Let propValue be GetValue(exprValue).
  5. ReturnIfAbrupt(propValue).
  6. Assert: enumerable is true.
  7. Return CreateDataPropertyOrThrow(object, propName, propValue).
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 IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let hasNameProperty be HasOwnProperty(propValue, "name").
    2. ReturnIfAbrupt(hasNameProperty).
    3. If hasNameProperty is false, perform SetFunctionName(propValue, propKey).
  7. Assert: enumerable is true.
  8. Return CreateDataPropertyOrThrow(object, propKey, propValue).

NOTE An alternative semantics for this production is given in B.3.1.

12.2.7 Function Defining Expressions

See 14.1 for PrimaryExpression : FunctionExpression .

See 14.4 for PrimaryExpression : GeneratorExpression .

See 14.5 for PrimaryExpression : ClassExpression .

12.2.8 Regular Expression Literals

Syntax

See 11.8.4.

12.2.8.1 Static Semantics: Early Errors

PrimaryExpression : RegularExpressionLiteral
  • It is a Syntax Error if BodyText of RegularExpressionLiteral cannot be recognized using the goal symbol Pattern of the ECMAScript RegExp grammar specified in 21.2.1.

  • It is a Syntax Error if FlagText of RegularExpressionLiteral contains any code points other than "g", "i", "m", "u", or "y", or if it contains the same code point more than once.

12.2.8.2 Runtime Semantics: Evaluation

PrimaryExpression : RegularExpressionLiteral
  1. Let pattern be the String value consisting of the UTF16Encoding of each code point of BodyText of RegularExpressionLiteral.
  2. Let flags be the String value consisting of the UTF16Encoding of each code point of FlagText of RegularExpressionLiteral.
  3. Return RegExpCreate(pattern, flags).

12.2.9 Template Literals

Syntax

TemplateLiteral[Yield] :
NoSubstitutionTemplate
TemplateHead Expression[In, ?Yield] TemplateSpans[?Yield]
TemplateSpans[Yield] :
TemplateTail
TemplateMiddleList[?Yield] TemplateTail
TemplateMiddleList[Yield] :
TemplateMiddle Expression[In, ?Yield]
TemplateMiddleList[?Yield] TemplateMiddle Expression[In, ?Yield]

12.2.9.1 Static Semantics: TemplateStrings

With parameter raw.

TemplateLiteral : NoSubstitutionTemplate
  1. If raw is false, then
    1. Let string be the TV of NoSubstitutionTemplate.
  2. Else,
    1. Let string be the TRV of NoSubstitutionTemplate.
  3. Return a List containing the single element, string.
TemplateLiteral : TemplateHead Expression TemplateSpans
  1. If raw is false, then
    1. Let head be the TV of TemplateHead.
  2. Else,
    1. Let head be the TRV of TemplateHead.
  3. Let tail be TemplateStrings of TemplateSpans with argument raw.
  4. Return a List containing head followed by the element, in order of tail.
TemplateSpans : TemplateTail
  1. If raw is false, then
    1. Let tail be the TV of TemplateTail.
  2. Else,
    1. Let tail be the TRV of TemplateTail.
  3. Return a List containing the single element, tail.
TemplateSpans : TemplateMiddleList TemplateTail
  1. Let middle be TemplateStrings of TemplateMiddleList with argument raw.
  2. If raw is false, then
    1. Let tail be the TV of TemplateTail.
  3. Else,
    1. Let tail be the TRV of TemplateTail.
  4. Return a List containing the elements, in order, of middle followed by tail.
TemplateMiddleList : TemplateMiddle Expression
  1. If raw is false, then
    1. Let string be the TV of TemplateMiddle.
  2. Else,
    1. Let string be the TRV of TemplateMiddle.
  3. Return a List containing the single element, string.
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. Let front be TemplateStrings of TemplateMiddleList with argument raw.
  2. If raw is false, then
    1. Let last be the TV of TemplateMiddle.
  3. Else,
    1. Let last be the TRV of TemplateMiddle.
  4. Append last as the last element of the List front.
  5. Return front.

12.2.9.2 Runtime Semantics: ArgumentListEvaluation

See also: 12.3.6.1

TemplateLiteral : NoSubstitutionTemplate
  1. Let templateLiteral be this TemplateLiteral.
  2. Let siteObj be GetTemplateObject(templateLiteral).
  3. Return a List containing the one element which is siteObj.
TemplateLiteral : TemplateHead Expression TemplateSpans
  1. Let templateLiteral be this TemplateLiteral.
  2. Let siteObj be GetTemplateObject(templateLiteral).
  3. Let firstSub be the result of evaluating Expression.
  4. ReturnIfAbrupt(firstSub).
  5. Let restSub be SubstitutionEvaluation of TemplateSpans.
  6. ReturnIfAbrupt(restSub).
  7. Assert: restSub is a List.
  8. Return a List whose first element is siteObj, whose second elements is firstSub, and whose subsequent elements are the elements of restSub, in order. restSub may contain no elements.

12.2.9.3 Runtime Semantics: GetTemplateObject ( templateLiteral )

The abstract operation GetTemplateObject is called with a grammar production, templateLiteral, as an argument. It performs the following steps:

  1. Let rawStrings be TemplateStrings of templateLiteral with argument true.
  2. Let ctx be the running execution context.
  3. Let realm be the ctx's Realm.
  4. Let templateRegistry be realm.[[templateMap]].
  5. For each element e of templateRegistry, do
    1. If e.[[strings]] and rawStrings contain the same values in the same order, then
      1. Return e.[[array]].
  6. Let cookedStrings be TemplateStrings of templateLiteral with argument false.
  7. Let count be the number of elements in the List cookedStrings.
  8. Let template be ArrayCreate(count).
  9. Let rawObj be ArrayCreate(count).
  10. Let index be 0.
  11. Repeat while index < count
    1. Let prop be ToString(index).
    2. Let cookedValue be the String value cookedStrings[index].
    3. Call template.[[DefineOwnProperty]](prop, PropertyDescriptor{[[Value]]: cookedValue, [[Enumerable]]: true, [[Writable]]: false, [[Configurable]]: false}).
    4. Let rawValue be the String value rawStrings[index].
    5. Call rawObj.[[DefineOwnProperty]](prop, PropertyDescriptor{[[Value]]: rawValue, [[Enumerable]]: true, [[Writable]]: false, [[Configurable]]: false}).
    6. Let index be index+1.
  12. Perform SetIntegrityLevel(rawObj, "frozen").
  13. Call template.[[DefineOwnProperty]]("raw", PropertyDescriptor{[[Value]]: rawObj, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false}).
  14. Perform SetIntegrityLevel(template, "frozen").
  15. Append the Record{[[strings]]: rawStrings, [[array]]: template} to templateRegistry.
  16. Return template.

NOTE 1 The creation of a template object cannot result in an abrupt completion.

NOTE 2 Each TemplateLiteral in the program code of a Realm is associated with a unique template object that is used in the evaluation of tagged Templates (12.2.9.5). The template objects are frozen and the same template object is used each time a specific tagged Template is evaluated. Whether template objects are created lazily upon first evaluation of the TemplateLiteral or eagerly prior to first evaluation is an implementation choice that is not observable to ECMAScript code.

NOTE 3 Future editions of this specification may define additional non-enumerable properties of template objects.

12.2.9.4 Runtime Semantics: SubstitutionEvaluation

TemplateSpans : TemplateTail
  1. Return an empty List.
TemplateSpans : TemplateMiddleList TemplateTail
  1. Return the result of SubstitutionEvaluation of TemplateMiddleList.
TemplateMiddleList : TemplateMiddle Expression
  1. Let sub be the result of evaluating Expression.
  2. ReturnIfAbrupt(sub).
  3. Return a List containing only sub.
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. Let preceding be the result of SubstitutionEvaluation of TemplateMiddleList .
  2. ReturnIfAbrupt(preceding).
  3. Let next be the result of evaluating Expression.
  4. ReturnIfAbrupt(next).
  5. Append next as the last element of the List preceding.
  6. Return preceding.

12.2.9.5 Runtime Semantics: Evaluation

TemplateLiteral : NoSubstitutionTemplate
  1. Return the String value whose code units are the elements of the TV of NoSubstitutionTemplate as defined in 11.8.6.
TemplateLiteral : TemplateHead Expression TemplateSpans
  1. Let head be the TV of TemplateHead as defined in 11.8.6.
  2. Let sub be the result of evaluating Expression.
  3. Let middle be ToString(sub).
  4. ReturnIfAbrupt(middle).
  5. Let tail be the result of evaluating TemplateSpans .
  6. ReturnIfAbrupt(tail).
  7. Return the String value whose code units are the elements of head followed by the elements of middle followed by the elements of tail.

NOTE 1 The string conversion semantics applied to the Expression value are like String.prototype.concat rather than the + operator.

TemplateSpans : TemplateTail
  1. Let tail be the TV of TemplateTail as defined in 11.8.6.
  2. Return the string consisting of the code units of tail.
TemplateSpans : TemplateMiddleList TemplateTail
  1. Let head be the result of evaluating TemplateMiddleList.
  2. ReturnIfAbrupt(head).
  3. Let tail be the TV of TemplateTail as defined in 11.8.6.
  4. Return the string whose code units are the elements of head followed by the elements of tail.
TemplateMiddleList : TemplateMiddle Expression
  1. Let head be the TV of TemplateMiddle as defined in 11.8.6.
  2. Let sub be the result of evaluating Expression.
  3. Let middle be ToString(sub).
  4. ReturnIfAbrupt(middle).
  5. Return the sequence of code units consisting of the code units of head followed by the elements of middle.

NOTE 2 The string conversion semantics applied to the Expression value are like String.prototype.concat rather than the + operator.

TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. Let rest be the result of evaluating TemplateMiddleList .
  2. ReturnIfAbrupt(rest).
  3. Let middle be the TV of TemplateMiddle as defined in 11.8.6.
  4. Let sub be the result of evaluating Expression.
  5. Let last be ToString(sub).
  6. ReturnIfAbrupt(last).
  7. Return the sequence of code units consisting of the elements of rest followed by the code units of middle followed by the elements of last.

NOTE 3 The string conversion semantics applied to the Expression value are like String.prototype.concat rather than the + operator.

12.2.10 The Grouping Operator

12.2.10.1 Static Semantics: Early Errors

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  • It is a Syntax Error if the lexical token sequence matched by CoverParenthesizedExpressionAndArrowParameterList cannot be parsed with no tokens left over using ParenthesizedExpression as the goal symbol.

  • All Early Errors rules for ParenthesizedExpression and its derived productions also apply to CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.

12.2.10.2 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

ParenthesizedExpression : ( Expression )
  1. Return IsFunctionDefinition of Expression.

12.2.10.3 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

ParenthesizedExpression : ( Expression )
  1. Return IsValidSimpleAssignmentTarget of Expression.

12.2.10.4 Runtime Semantics: Evaluation

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return the result of evaluating expr.
ParenthesizedExpression : ( Expression )
  1. Return the result of evaluating Expression. This may be of type Reference.

NOTE This algorithm does not apply GetValue to the result of evaluating Expression. The principal motivation for this is so that operators such as delete and typeof may be applied to parenthesized expressions.

12.3 Left-Hand-Side Expressions

Syntax

MemberExpression[Yield] :
PrimaryExpression[?Yield]
MemberExpression[?Yield] [ Expression[In, ?Yield] ]
MemberExpression[?Yield] . IdentifierName
MemberExpression[?Yield] TemplateLiteral[?Yield]
SuperProperty[?Yield]
MetaProperty
new MemberExpression[?Yield] Arguments[?Yield]
SuperProperty[Yield] :
super [ Expression[In, ?Yield] ]
super . IdentifierName
MetaProperty :
NewTarget
NewTarget :
new . target
NewExpression[Yield] :
MemberExpression[?Yield]
new NewExpression[?Yield]
CallExpression[Yield] :
MemberExpression[?Yield] Arguments[?Yield]
SuperCall[?Yield]
CallExpression[?Yield] Arguments[?Yield]
CallExpression[?Yield] [ Expression[In, ?Yield] ]
CallExpression[?Yield] . IdentifierName
CallExpression[?Yield] TemplateLiteral[?Yield]
SuperCall[Yield] :
super Arguments[?Yield]
Arguments[Yield] :
( )
( ArgumentList[?Yield] )
ArgumentList[Yield] :
AssignmentExpression[In, ?Yield]
... AssignmentExpression[In, ?Yield]
ArgumentList[?Yield] , AssignmentExpression[In, ?Yield]
ArgumentList[?Yield] , ... AssignmentExpression[In, ?Yield]
LeftHandSideExpression[Yield] :
NewExpression[?Yield]
CallExpression[?Yield]

12.3.1 Static Semantics

12.3.1.1 Static Semantics: Contains

With parameter symbol.

See also: 5.3, 12.2.6.3, 14.1.4, 14.2.3, 14.4.4, 14.5.4

MemberExpression : MemberExpression . IdentifierName
  1. If MemberExpression Contains symbol is true, return true.
  2. If symbol is a ReservedWord, return false.
  3. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true;
  4. Return false.
SuperProperty : super . IdentifierName
  1. If symbol is the ReservedWord super, return true.
  2. If symbol is a ReservedWord, return false.
  3. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true;
  4. Return false.
CallExpression : CallExpression . IdentifierName
  1. If CallExpression Contains symbol is true, return true.
  2. If symbol is a ReservedWord, return false.
  3. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true;
  4. Return false.

12.3.1.2 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

MemberExpression :
MemberExpression [ Expression ]
MemberExpression . IdentifierName
MemberExpression TemplateLiteral
SuperProperty
MetaProperty
new MemberExpression Arguments
NewExpression :
new NewExpression
CallExpression :
MemberExpression Arguments
SuperCall
CallExpression Arguments
CallExpression [ Expression ]
CallExpression . IdentifierName
CallExpression TemplateLiteral
  1. Return false.

12.3.1.3 Static Semantics: IsDestructuring

See also: 13.7.5.6.

MemberExpression : PrimaryExpression
  1. If PrimaryExpression is either an ObjectLiteral or an ArrayLiteral, return true.
  2. Return false.
MemberExpression :
MemberExpression [ Expression ]
MemberExpression . IdentifierName
MemberExpression TemplateLiteral
SuperProperty
MetaProperty
new MemberExpression Arguments
NewExpression :
new NewExpression
CallExpression :
MemberExpression Arguments
SuperCall
CallExpression Arguments
CallExpression [ Expression ]
CallExpression . IdentifierName
CallExpression TemplateLiteral
  1. Return false.

12.3.1.4 Static Semantics: IsIdentifierRef

See also: 12.2.1.4.

LeftHandSideExpression :
CallExpression
MemberExpression :
MemberExpression [ Expression ]
MemberExpression . IdentifierName
MemberExpression TemplateLiteral
SuperProperty
MetaProperty
new MemberExpression Arguments
NewExpression :
new NewExpression
  1. Return false.

12.3.1.5 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

CallExpression :
CallExpression [ Expression ]
CallExpression . IdentifierName
MemberExpression :
MemberExpression [ Expression ]
MemberExpression . IdentifierName
SuperProperty
  1. Return true.
CallExpression :
MemberExpression Arguments
SuperCall
CallExpression Arguments
CallExpression TemplateLiteral
NewExpression :
new NewExpression
MemberExpression :
MemberExpression TemplateLiteral
new MemberExpression Arguments
NewTarget :
new . target
  1. Return false.

12.3.2 Property Accessors

NOTE Properties are accessed by name, using either the dot notation:

MemberExpression . IdentifierName
CallExpression . IdentifierName

or the bracket notation:

MemberExpression [ Expression ]
CallExpression [ Expression ]

The dot notation is explained by the following syntactic conversion:

MemberExpression . IdentifierName

is identical in its behaviour to

MemberExpression [ <identifier-name-string> ]

and similarly

CallExpression . IdentifierName

is identical in its behaviour to

CallExpression [ <identifier-name-string> ]

where <identifier-name-string> is the result of evaluating StringValue of IdentifierName.

12.3.2.1 Runtime Semantics: Evaluation

MemberExpression : MemberExpression [ Expression ]
  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be GetValue(baseReference).
  3. ReturnIfAbrupt(baseValue).
  4. Let propertyNameReference be the result of evaluating Expression.
  5. Let propertyNameValue be GetValue(propertyNameReference).
  6. ReturnIfAbrupt(propertyNameValue).
  7. Let bv be RequireObjectCoercible(baseValue).
  8. ReturnIfAbrupt(bv).
  9. Let propertyKey be ToPropertyKey(propertyNameValue).
  10. ReturnIfAbrupt(propertyKey).
  11. If the code matched by the syntactic production that is being evaluated is strict mode code, let strict be true, else let strict be false.
  12. Return a value of type Reference whose base value is bv and whose referenced name is propertyKey, and whose strict reference flag is strict.
MemberExpression : MemberExpression . IdentifierName
  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be GetValue(baseReference).
  3. ReturnIfAbrupt(baseValue).
  4. Let bv be RequireObjectCoercible(baseValue).
  5. ReturnIfAbrupt(bv).
  6. Let propertyNameString be StringValue of IdentifierName
  7. If the code matched by the syntactic production that is being evaluated is strict mode code, let strict be true, else let strict be false.
  8. Return a value of type Reference whose base value is bv and whose referenced name is propertyNameString, and whose strict reference flag is strict.
CallExpression : CallExpression [ Expression ]

Is evaluated in exactly the same manner as MemberExpression : MemberExpression [ Expression ] except that the contained CallExpression is evaluated in step 1.

CallExpression : CallExpression . IdentifierName

Is evaluated in exactly the same manner as MemberExpression : MemberExpression . IdentifierName except that the contained CallExpression is evaluated in step 1.

12.3.3 The new Operator

12.3.3.1 Runtime Semantics: Evaluation

NewExpression : new NewExpression
  1. Return EvaluateNew(NewExpression, empty).
MemberExpression : new MemberExpression Arguments
  1. Return EvaluateNew(MemberExpression, Arguments).

12.3.3.1.1 Runtime Semantics: EvaluateNew(constructProduction, arguments)

The abstract operation EvaluateNew with arguments constructProduction, and arguments performs the following steps:

  1. Assert: constructProduction is either a NewExpression or a MemberExpression.
  2. Assert: arguments is either empty or an Arguments production.
  3. Let ref be the result of evaluating constructProduction.
  4. Let constructor be GetValue(ref).
  5. ReturnIfAbrupt(constructor).
  6. If arguments is empty, let argList be an empty List.
  7. Else,
    1. Let argList be ArgumentListEvaluation of arguments.
    2. ReturnIfAbrupt(argList).
  8. If IsConstructor (constructor) is false, throw a TypeError exception.
  9. Return Construct(constructor, argList).

12.3.4 Function Calls

12.3.4.1 Runtime Semantics: Evaluation

CallExpression : MemberExpression Arguments
  1. Let ref be the result of evaluating MemberExpression.
  2. Let func be GetValue(ref).
  3. ReturnIfAbrupt(func).
  4. If Type(ref) is Reference and IsPropertyReference(ref) is false and GetReferencedName(ref) is "eval", then
    1. If SameValue(func, %eval%) is true, then
      1. Let argList be ArgumentListEvaluation(Arguments).
      2. ReturnIfAbrupt(argList).
      3. If argList has no elements, return undefined.
      4. Let evalText be the first element of argList.
      5. If the source code matching this CallExpression is strict code, let strictCaller be true. Otherwise let strictCaller be false.
      6. Let evalRealm be the running execution context's Realm.
      7. Return PerformEval(evalText, evalRealm, strictCaller, true). .
  5. If Type(ref) is Reference, then
    1. If IsPropertyReference(ref) is true, then
      1. Let thisValue be GetThisValue(ref).
    2. Else, the base of ref is an Environment Record
      1. Let refEnv be GetBase(ref).
      2. Let thisValue be refEnv.WithBaseObject().
  6. Else Type(ref) is not Reference,
    1. Let thisValue be undefined.
  7. Let thisCall be this CallExpression.
  8. Let tailCall be IsInTailPosition(thisCall). (See 14.6.1)
  9. Return EvaluateDirectCall(func, thisValue, Arguments, tailCall).

A CallExpression evaluation that executes step 4.a.vii is a direct eval.

CallExpression : CallExpression Arguments
  1. Let ref be the result of evaluating CallExpression.
  2. Let thisCall be this CallExpression
  3. Let tailCall be IsInTailPosition(thisCall). (See 14.6.1)
  4. Return EvaluateCall(ref, Arguments, tailCall).

12.3.4.2 Runtime Semantics: EvaluateCall( ref, arguments, tailPosition )

The abstract operation EvaluateCall takes as arguments a value ref, a syntactic grammar production arguments, and a Boolean argument tailPosition. It performs the following steps:

  1. Let func be GetValue(ref).
  2. ReturnIfAbrupt(func).
  3. If Type(ref) is Reference, then
    1. If IsPropertyReference(ref) is true, then
      1. Let thisValue be GetThisValue(ref).
    2. Else, the base of ref is an Environment Record
      1. Let refEnv be GetBase(ref).
      2. Let thisValue be refEnv.WithBaseObject().
  4. Else Type(ref) is not Reference,
    1. Let thisValue be undefined.
  5. Return EvaluateDirectCall(func, thisValue, arguments, tailPosition).

12.3.4.3 Runtime Semantics: EvaluateDirectCall( func, thisValue, arguments, tailPosition )

The abstract operation EvaluateDirectCall takes as arguments a value func, a value thisValue, a syntactic grammar production arguments, and a Boolean argument tailPosition. It performs the following steps:

  1. Let argList be ArgumentListEvaluation(arguments).
  2. ReturnIfAbrupt(argList).
  3. If Type(func) is not Object, throw a TypeError exception.
  4. If IsCallable(func) is false, throw a TypeError exception.
  5. If tailPosition is true, perform PrepareForTailCall().
  6. Let result be Call(func, thisValue, argList).
  7. Assert: If tailPosition is true, the above call will not return here, but instead evaluation will continue as if the following return has already occurred.
  8. Assert: If result is not an abrupt completion then Type(result) is an ECMAScript language type.
  9. Return result.

12.3.5 The super Keyword

12.3.5.1 Runtime Semantics: Evaluation

SuperProperty : super [ Expression ]
  1. Let propertyNameReference be the result of evaluating Expression.
  2. Let propertyNameValue be GetValue(propertyNameReference).
  3. Let propertyKey be ToPropertyKey(propertyNameValue).
  4. ReturnIfAbrupt(propertyKey).
  5. If the code matched by the syntactic production that is being evaluated is strict mode code, let strict be true, else let strict be false.
  6. Return MakeSuperPropertyReference(propertyKey, strict).
SuperProperty : super . IdentifierName
  1. Let propertyKey be StringValue of IdentifierName.
  2. If the code matched by the syntactic production that is being evaluated is strict mode code, let strict be true, else let strict be false.
  3. Return MakeSuperPropertyReference(propertyKey, strict).
SuperCall : super Arguments
  1. Let newTarget be GetNewTarget().
  2. If newTarget is undefined, throw a ReferenceError exception.
  3. Let func be GetSuperConstructor().
  4. ReturnIfAbrupt(func).
  5. Let argList be ArgumentListEvaluation of Arguments.
  6. ReturnIfAbrupt(argList).
  7. Let result be Construct(func, argList, newTarget).
  8. ReturnIfAbrupt(result).
  9. Let thisER be GetThisEnvironment( ).
  10. Return thisER.BindThisValue(result).

12.3.5.2 Runtime Semantics: GetSuperConstructor ( )

The abstract operation GetSuperConstructor performs the following steps:

  1. Let envRec be GetThisEnvironment( ).
  2. Assert: envRec is a function Environment Record.
  3. Let activeFunction be envRec.[[FunctionObject]].
  4. Let superConstructor be activeFunction.[[GetPrototypeOf]]().
  5. ReturnIfAbrupt(superConstructor).
  6. If IsConstructor(superConstructor) is false, throw a TypeError exception.
  7. Return superConstructor.

12.3.5.3 Runtime Semantics: MakeSuperPropertyReference(propertyKey, strict)

The abstract operation MakeSuperPropertyReference with arguments propertyKey and strict performs the following steps:

  1. Let env be GetThisEnvironment( ).
  2. If env.HasSuperBinding() is false, throw a ReferenceError exception.
  3. Let actualThis be env.GetThisBinding().
  4. ReturnIfAbrupt(actualThis).
  5. Let baseValue be env.GetSuperBase().
  6. Let bv be RequireObjectCoercible(baseValue).
  7. ReturnIfAbrupt(bv).
  8. Return a value of type Reference that is a Super Reference whose base value is bv, whose referenced name is propertyKey, whose thisValue is actualThis, and whose strict reference flag is strict.

12.3.6 Argument Lists

NOTE The evaluation of an argument list produces a List of values (see 6.2.1).

12.3.6.1 Runtime Semantics: ArgumentListEvaluation

See also: 12.2.9.2

Arguments : ( )
  1. Return an empty List.
ArgumentList : AssignmentExpression
  1. Let ref be the result of evaluating AssignmentExpression.
  2. Let arg be GetValue(ref).
  3. ReturnIfAbrupt(arg).
  4. Return a List whose sole item is arg.
ArgumentList : ... AssignmentExpression
  1. Let list be an empty List.
  2. Let spreadRef be the result of evaluating AssignmentExpression.
  3. Let spreadObj be GetValue(spreadRef).
  4. Let iterator be GetIterator(spreadObj).
  5. ReturnIfAbrupt(iterator).
  6. Repeat
    1. Let next be IteratorStep(iterator).
    2. ReturnIfAbrupt(next).
    3. If next is false, return list.
    4. Let nextArg be IteratorValue(next).
    5. ReturnIfAbrupt(nextArg).
    6. Append nextArg as the last element of list.
ArgumentList : ArgumentList , AssignmentExpression
  1. Let precedingArgs be the result of evaluating ArgumentList.
  2. ReturnIfAbrupt(precedingArgs).
  3. Let ref be the result of evaluating AssignmentExpression.
  4. Let arg be GetValue(ref).
  5. ReturnIfAbrupt(arg).
  6. Append arg to the end of precedingArgs.
  7. Return precedingArgs.
ArgumentList : ArgumentList , ... AssignmentExpression
  1. Let precedingArgs be the result of evaluating ArgumentList.
  2. Let spreadRef be the result of evaluating AssignmentExpression.
  3. Let iterator be GetIterator(GetValue(spreadRef) ).
  4. ReturnIfAbrupt(iterator).
  5. Repeat
    1. Let next be IteratorStep(iterator).
    2. ReturnIfAbrupt(next).
    3. If next is false, return precedingArgs.
    4. Let nextArg be IteratorValue(next).
    5. ReturnIfAbrupt(nextArg).
    6. Append nextArg as the last element of precedingArgs.

12.3.7 Tagged Templates

NOTE A tagged template is a function call where the arguments of the call are derived from a TemplateLiteral (12.2.9). The actual arguments include a template object (12.2.9.3) and the values produced by evaluating the expressions embedded within the TemplateLiteral.

12.3.7.1 Runtime Semantics: Evaluation

MemberExpression : MemberExpression TemplateLiteral
  1. Let tagRef be the result of evaluating MemberExpression.
  2. Let thisCall be this MemberExpression.
  3. Let tailCall be IsInTailPosition(thisCall). (See 14.6.1)
  4. Return EvaluateCall(tagRef, TemplateLiteral, tailCall).
CallExpression : CallExpression TemplateLiteral
  1. Let tagRef be the result of evaluating CallExpression.
  2. Let thisCall be this CallExpression.
  3. Let tailCall be IsInTailPosition(thisCall). (See 14.6.1)
  4. Return EvaluateCall(tagRef, TemplateLiteral, tailCall).

12.3.8 Meta Properties

12.3.8.1 Runtime Semantics: Evaluation

NewTarget : new . target
  1. Return GetNewTarget().

12.4 Postfix Expressions

Syntax

PostfixExpression[Yield] :
LeftHandSideExpression[?Yield]
LeftHandSideExpression[?Yield] [no LineTerminator here] ++
LeftHandSideExpression[?Yield] [no LineTerminator here] --

12.4.1 Static Semantics: Early Errors

PostfixExpression :
LeftHandSideExpression ++
LeftHandSideExpression --
  • It is an early Reference Error if IsValidSimpleAssignmentTarget of LeftHandSideExpression is false.

12.4.2 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8

PostfixExpression :
LeftHandSideExpression ++
LeftHandSideExpression --
  1. Return false.

12.4.3 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

PostfixExpression :
LeftHandSideExpression ++
LeftHandSideExpression --
  1. Return false.

12.4.4 Postfix Increment Operator

12.4.4.1 Runtime Semantics: Evaluation

PostfixExpression : LeftHandSideExpression ++
  1. Let lhs be the result of evaluating LeftHandSideExpression.
  2. Let oldValue be ToNumber(GetValue(lhs)).
  3. ReturnIfAbrupt(oldValue).
  4. Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see 12.7.5).
  5. Let status be PutValue(lhs, newValue).
  6. ReturnIfAbrupt(status).
  7. Return oldValue.

12.4.5 Postfix Decrement Operator

12.4.5.1 Runtime Semantics: Evaluation

PostfixExpression : LeftHandSideExpression --
  1. Let lhs be the result of evaluating LeftHandSideExpression.
  2. Let oldValue be ToNumber(GetValue(lhs)).
  3. ReturnIfAbrupt(oldValue).
  4. Let newValue be the result of subtracting the value 1 from oldValue, using the same rules as for the - operator (12.7.5).
  5. Let status be PutValue(lhs, newValue).
  6. ReturnIfAbrupt(status).
  7. Return oldValue.

12.5 Unary Operators

Syntax

UnaryExpression[Yield] :
PostfixExpression[?Yield]
delete UnaryExpression[?Yield]
void UnaryExpression[?Yield]
typeof UnaryExpression[?Yield]
++ UnaryExpression[?Yield]
-- UnaryExpression[?Yield]
+ UnaryExpression[?Yield]
- UnaryExpression[?Yield]
~ UnaryExpression[?Yield]
! UnaryExpression[?Yield]

12.5.1 Static Semantics: Early Errors

UnaryExpression :
++ UnaryExpression
-- UnaryExpression
  • It is an early Reference Error if IsValidSimpleAssignmentTarget of UnaryExpression is false.

12.5.2 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

UnaryExpression :
delete UnaryExpression
void UnaryExpression
typeof UnaryExpression
++ UnaryExpression
-- UnaryExpression
+ UnaryExpression
- UnaryExpression
~ UnaryExpression
! UnaryExpression
  1. Return false.

12.5.3 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

UnaryExpression :
delete UnaryExpression
void UnaryExpression
typeof UnaryExpression
++ UnaryExpression
-- UnaryExpression
+ UnaryExpression
- UnaryExpression
~ UnaryExpression
! UnaryExpression
  1. Return false.

12.5.4 The delete Operator

12.5.4.1 Static Semantics: Early Errors

UnaryExpression : delete UnaryExpression
  • It is a Syntax Error if the UnaryExpression is contained in strict mode code and the derived UnaryExpression is PrimaryExpression : IdentifierReference.

  • It is a Syntax Error if the derived UnaryExpression is
    PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
    and CoverParenthesizedExpressionAndArrowParameterList ultimately derives a phrase that, if used in place of UnaryExpression, would produce a Syntax Error according to these rules. This rule is recursively applied.

NOTE The last rule means that expressions such as
delete (((foo)))
produce early errors because of recursive application of the first rule.

12.5.4.2 Runtime Semantics: Evaluation

UnaryExpression : delete UnaryExpression
  1. Let ref be the result of evaluating UnaryExpression.
  2. ReturnIfAbrupt(ref).
  3. If Type(ref) is not Reference, return true.
  4. If IsUnresolvableReference(ref) is true, then
    1. Assert: IsStrictReference(ref) is false.
    2. Return true.
  5. If IsPropertyReference(ref) is true, then
    1. If IsSuperReference(ref), throw a ReferenceError exception.
    2. Let baseObj be ToObject(GetBase(ref)).
    3. Assert: baseObj is not an abrupt completion.
    4. Let deleteStatus be baseObj.[[Delete]](GetReferencedName(ref)).
    5. ReturnIfAbrupt(deleteStatus).
    6. If deleteStatus is false and IsStrictReference(ref) is true, throw a TypeError exception.
    7. Return deleteStatus.
  6. Else ref is a Reference to an Environment Record binding,
    1. Let bindings be GetBase(ref).
    2. Return bindings.DeleteBinding(GetReferencedName(ref)).

NOTE When a delete operator occurs within strict mode code, a SyntaxError exception is thrown if its UnaryExpression is a direct reference to a variable, function argument, or function name. In addition, if a delete operator occurs within strict mode code and the property to be deleted has the attribute { [[Configurable]]: false }, a TypeError exception is thrown.

12.5.5 The void Operator

12.5.5.1 Runtime Semantics: Evaluation

UnaryExpression : void UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let status be GetValue(expr).
  3. ReturnIfAbrupt(status).
  4. Return undefined.

NOTE GetValue must be called even though its value is not used because it may have observable side-effects.

12.5.6 The typeof Operator

12.5.6.1 Runtime Semantics: Evaluation

UnaryExpression : typeof UnaryExpression
  1. Let val be the result of evaluating UnaryExpression.
  2. If Type(val) is Reference, then
    1. If IsUnresolvableReference(val) is true, return "undefined".
  3. Let val be GetValue(val).
  4. ReturnIfAbrupt(val).
  5. Return a String according to { REF _Ref327355399 \h \* MERGEFORMAT }Table 35.
Table 35 — typeof Operator Results
Type of val Result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
Object (ordinary and does not implement [[Call]]) "object"
Object (standard exotic and does not implement [[Call]]) "object"
Object (implements [[Call]]) "function"
Object (non-standard exotic and does not implement [[Call]]) Implementation-defined. Must not be "undefined", "boolean", "function", "number", "symbol", or "string".

NOTE Implementations are discouraged from defining new typeof result values for non-standard exotic objects. If possible "object"should be used for such objects.

12.5.7 Prefix Increment Operator

12.5.7.1 Runtime Semantics: Evaluation

UnaryExpression : ++ UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ToNumber(GetValue(expr)).
  3. ReturnIfAbrupt(oldValue).
  4. Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see 12.7.5).
  5. Let status be PutValue(expr, newValue).
  6. ReturnIfAbrupt(status).
  7. Return newValue.

12.5.8 Prefix Decrement Operator

12.5.8.1 Runtime Semantics: Evaluation

UnaryExpression : -- UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ToNumber(GetValue(expr)).
  3. ReturnIfAbrupt(oldValue).
  4. Let newValue be the result of subtracting the value 1 from oldValue, using the same rules as for the - operator (see 12.7.5).
  5. Let status be PutValue(expr, newValue).
  6. ReturnIfAbrupt(status).
  7. Return newValue.

12.5.9 Unary + Operator

NOTE The unary + operator converts its operand to Number type.

12.5.9.1 Runtime Semantics: Evaluation

UnaryExpression : + UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Return ToNumber(GetValue(expr)).

12.5.10 Unary - Operator

NOTE The unary - operator converts its operand to Number type and then negates it. Negating +0 produces −0, and negating −0 produces +0.

12.5.10.1 Runtime Semantics: Evaluation

UnaryExpression : - UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ToNumber(GetValue(expr)).
  3. ReturnIfAbrupt(oldValue).
  4. If oldValue is NaN, return NaN.
  5. Return the result of negating oldValue; that is, compute a Number with the same magnitude but opposite sign.

12.5.11 Bitwise NOT Operator ( ~ )

12.5.11.1 Runtime Semantics: Evaluation

UnaryExpression : ~ UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ToInt32(GetValue(expr)).
  3. ReturnIfAbrupt(oldValue).
  4. Return the result of applying bitwise complement to oldValue. The result is a signed 32-bit integer.

12.5.12 Logical NOT Operator ( ! )

12.5.12.1 Runtime Semantics: Evaluation

UnaryExpression : ! UnaryExpression
  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ToBoolean(GetValue(expr)).
  3. ReturnIfAbrupt(oldValue).
  4. If oldValue is true, return false.
  5. Return true.

12.6 Multiplicative Operators

Syntax

MultiplicativeExpression[Yield] :
UnaryExpression[?Yield]
MultiplicativeExpression[?Yield] MultiplicativeOperator UnaryExpression[?Yield]
MultiplicativeOperator : one of
* / %

12.6.1 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator UnaryExpression

  1. Return false.

12.6.2 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator UnaryExpression

  1. Return false.

12.6.3 Runtime Semantics: Evaluation

MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator UnaryExpression

  1. Let left be the result of evaluating MultiplicativeExpression.
  2. Let leftValue be GetValue(left).
  3. ReturnIfAbrupt(leftValue).
  4. Let right be the result of evaluating UnaryExpression.
  5. Let rightValue be GetValue(right).
  6. Let lnum be ToNumber(leftValue).
  7. ReturnIfAbrupt(lnum).
  8. Let rnum be ToNumber(rightValue).
  9. ReturnIfAbrupt(rnum).
  10. Return the result of applying the MultiplicativeOperator (*, /, or %) to lnum and rnum as specified in 12.6.3.1, 12.6.3.2, or 12.6.3.3.

12.6.3.1 Applying the * Operator

The * MultiplicativeOperator performs multiplication, producing the product of its operands. Multiplication is commutative. Multiplication is not always associative in ECMAScript, because of finite precision.

The result of a floating-point multiplication is governed by the rules of IEEE 754-2008 binary double-precision arithmetic:

  • If either operand is NaN, the result is NaN.

  • The sign of the result is positive if both operands have the same sign, negative if the operands have different signs.

  • Multiplication of an infinity by a zero results in NaN.

  • Multiplication of an infinity by an infinity results in an infinity. The sign is determined by the rule already stated above.

  • Multiplication of an infinity by a finite nonzero value results in a signed infinity. The sign is determined by the rule already stated above.

  • In the remaining cases, where neither an infinity nor NaN is involved, the product is computed and rounded to the nearest representable value using IEEE 754-2008 round-to-nearest mode. If the magnitude is too large to represent, the result is then an infinity of appropriate sign. If the magnitude is too small to represent, the result is then a zero of appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754-2008.

12.6.3.2 Applying the / Operator

The / MultiplicativeOperator performs division, producing the quotient of its operands. The left operand is the dividend and the right operand is the divisor. ECMAScript does not perform integer division. The operands and result of all division operations are double-precision floating-point numbers. The result of division is determined by the specification of IEEE 754-2008 arithmetic:

  • If either operand is NaN, the result is NaN.

  • The sign of the result is positive if both operands have the same sign, negative if the operands have different signs.

  • Division of an infinity by an infinity results in NaN.

  • Division of an infinity by a zero results in an infinity. The sign is determined by the rule already stated above.

  • Division of an infinity by a nonzero finite value results in a signed infinity. The sign is determined by the rule already stated above.

  • Division of a finite value by an infinity results in zero. The sign is determined by the rule already stated above.

  • Division of a zero by a zero results in NaN; division of zero by any other finite value results in zero, with the sign determined by the rule already stated above.

  • Division of a nonzero finite value by a zero results in a signed infinity. The sign is determined by the rule already stated above.

  • In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the quotient is computed and rounded to the nearest representable value using IEEE 754-2008 round-to-nearest mode. If the magnitude is too large to represent, the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of the appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754-2008.

12.6.3.3 Applying the % Operator

The % MultiplicativeOperator yields the remainder of its operands from an implied division; the left operand is the dividend and the right operand is the divisor.

NOTE In C and C++, the remainder operator accepts only integral operands; in ECMAScript, it also accepts floating-point operands.

The result of a floating-point remainder operation as computed by the % operator is not the same as the “remainder” operation defined by IEEE 754-2008. The IEEE 754-2008 “remainder” operation computes the remainder from a rounding division, not a truncating division, and so its behaviour is not analogous to that of the usual integer remainder operator. Instead the ECMAScript language defines % on floating-point operations to behave in a manner analogous to that of the Java integer remainder operator; this may be compared with the C library function fmod.

The result of an ECMAScript floating-point remainder operation is determined by the rules of IEEE arithmetic:

  • If either operand is NaN, the result is NaN.

  • The sign of the result equals the sign of the dividend.

  • If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.

  • If the dividend is finite and the divisor is an infinity, the result equals the dividend.

  • If the dividend is a zero and the divisor is nonzero and finite, the result is the same as the dividend.

  • In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the floating-point remainder r from a dividend n and a divisor d is defined by the mathematical relation r = n − (d × q) where q is an integer that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d. r is computed and rounded to the nearest representable value using IEEE 754-2008 round-to-nearest mode.

12.7 Additive Operators

Syntax

AdditiveExpression[Yield] :
MultiplicativeExpression[?Yield]
AdditiveExpression[?Yield] + MultiplicativeExpression[?Yield]
AdditiveExpression[?Yield] - MultiplicativeExpression[?Yield]

12.7.1 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

AdditiveExpression :
AdditiveExpression + MultiplicativeExpression
AdditiveExpression - MultiplicativeExpression
  1. Return false.

12.7.2 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

AdditiveExpression :
AdditiveExpression + MultiplicativeExpression
AdditiveExpression - MultiplicativeExpression
  1. Return false.

12.7.3 The Addition operator ( + )

NOTE The addition operator either performs string concatenation or numeric addition.

12.7.3.1 Runtime Semantics: Evaluation

AdditiveExpression : AdditiveExpression + MultiplicativeExpression
  1. Let lref be the result of evaluating AdditiveExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating MultiplicativeExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Let lprim be ToPrimitive(lval).
  8. ReturnIfAbrupt(lprim).
  9. Let rprim be ToPrimitive(rval).
  10. ReturnIfAbrupt(rprim).
  11. If Type(lprim) is String or Type(rprim) is String, then
    1. Let lstr be ToString(lprim).
    2. ReturnIfAbrupt(lstr).
    3. Let rstr be ToString(rprim).
    4. ReturnIfAbrupt(rstr).
    5. Return the String that is the result of concatenating lstr and rstr.
  12. Let lnum be ToNumber(lprim).
  13. ReturnIfAbrupt(lnum).
  14. Let rnum be ToNumber(rprim).
  15. ReturnIfAbrupt(rnum).
  16. Return the result of applying the addition operation to lnum and rnum. See the Note below 12.7.5.

NOTE 1 No hint is provided in the calls to ToPrimitive in steps 7 and 9. All standard objects except Date objects handle the absence of a hint as if the hint Number were given; Date objects handle the absence of a hint as if the hint String were given. Exotic objects may handle the absence of a hint in some other manner.

NOTE 2 Step 11 differs from step 5 of the Abstract Relational Comparison algorithm (7.2.11), by using the logical-or operation instead of the logical-and operation.

12.7.4 The Subtraction Operator ( - )

12.7.4.1 Runtime Semantics: Evaluation

AdditiveExpression : AdditiveExpression - MultiplicativeExpression
  1. Let lref be the result of evaluating AdditiveExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating MultiplicativeExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Let lnum be ToNumber(lval).
  8. ReturnIfAbrupt(lnum).
  9. Let rnum be ToNumber(rval).
  10. ReturnIfAbrupt(rnum).
  11. Return the result of applying the subtraction operation to lnum and rnum. See the note below 12.7.5.

12.7.5 Applying the Additive Operators to Numbers

The + operator performs addition when applied to two operands of numeric type, producing the sum of the operands. The - operator performs subtraction, producing the difference of two numeric operands.

Addition is a commutative operation, but not always associative.

The result of an addition is determined using the rules of IEEE 754-2008 binary double-precision arithmetic:

  • If either operand is NaN, the result is NaN.

  • The sum of two infinities of opposite sign is NaN.

  • The sum of two infinities of the same sign is the infinity of that sign.

  • The sum of an infinity and a finite value is equal to the infinite operand.

  • The sum of two negative zeroes is −0. The sum of two positive zeroes, or of two zeroes of opposite sign, is +0.

  • The sum of a zero and a nonzero finite value is equal to the nonzero operand.

  • The sum of two nonzero finite values of the same magnitude and opposite sign is +0.

  • In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, and the operands have the same sign or have different magnitudes, the sum is computed and rounded to the nearest representable value using IEEE 754-2008 round-to-nearest mode. If the magnitude is too large to represent, the operation overflows and the result is then an infinity of appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754-2008.

NOTE The - operator performs subtraction when applied to two operands of numeric type, producing the difference of its operands; the left operand is the minuend and the right operand is the subtrahend. Given numeric operands a and b, it is always the case that ab produces the same result as a +(–b).

12.8 Bitwise Shift Operators

Syntax

ShiftExpression[Yield] :
AdditiveExpression[?Yield]
ShiftExpression[?Yield] << AdditiveExpression[?Yield]
ShiftExpression[?Yield] >> AdditiveExpression[?Yield]
ShiftExpression[?Yield] >>> AdditiveExpression[?Yield]

12.8.1 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

ShiftExpression :
ShiftExpression << AdditiveExpression
ShiftExpression >> AdditiveExpression
ShiftExpression >>> AdditiveExpression
  1. Return false.

12.8.2 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

ShiftExpression :
ShiftExpression << AdditiveExpression
ShiftExpression >> AdditiveExpression
ShiftExpression >>> AdditiveExpression
  1. Return false.

12.8.3 The Left Shift Operator ( << )

NOTE Performs a bitwise left shift operation on the left operand by the amount specified by the right operand.

12.8.3.1 Runtime Semantics: Evaluation

ShiftExpression : ShiftExpression << AdditiveExpression
  1. Let lref be the result of evaluating ShiftExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating AdditiveExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Let lnum be ToInt32(lval).
  8. ReturnIfAbrupt(lnum).
  9. Let rnum be ToUint32(rval).
  10. ReturnIfAbrupt(rnum).
  11. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  12. Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.

12.8.4 The Signed Right Shift Operator ( >> )

NOTE Performs a sign-filling bitwise right shift operation on the left operand by the amount specified by the right operand.

12.8.4.1 Runtime Semantics: Evaluation

ShiftExpression : ShiftExpression >> AdditiveExpression
  1. Let lref be the result of evaluating ShiftExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating AdditiveExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Let lnum be ToInt32(lval).
  8. ReturnIfAbrupt(lnum).
  9. Let rnum be ToUint32(rval).
  10. ReturnIfAbrupt(rnum).
  11. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  12. Return the result of performing a sign-extending right shift of lnum by shiftCount bits. The most significant bit is propagated. The result is a signed 32-bit integer.

12.8.5 The Unsigned Right Shift Operator ( >>> )

NOTE Performs a zero-filling bitwise right shift operation on the left operand by the amount specified by the right operand.

12.8.5.1 Runtime Semantics: Evaluation

ShiftExpression : ShiftExpression >>> AdditiveExpression
  1. Let lref be the result of evaluating ShiftExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating AdditiveExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Let lnum be ToUint32(lval).
  8. ReturnIfAbrupt(lnum).
  9. Let rnum be ToUint32(rval).
  10. ReturnIfAbrupt(rnum).
  11. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  12. Return the result of performing a zero-filling right shift of lnum by shiftCount bits. Vacated bits are filled with zero. The result is an unsigned 32-bit integer.

12.9 Relational Operators

NOTE 1 The result of evaluating a relational operator is always of type Boolean, reflecting whether the relationship named by the operator holds between its two operands.

Syntax

RelationalExpression[In, Yield] :
ShiftExpression[?Yield]
RelationalExpression[?In, ?Yield] < ShiftExpression[?Yield]
RelationalExpression[?In, ?Yield] > ShiftExpression[?Yield]
RelationalExpression[?In, ?Yield] <= ShiftExpression[? Yield]
RelationalExpression[?In, ?Yield] >= ShiftExpression[?Yield]
RelationalExpression[?In, ?Yield] instanceof ShiftExpression[?Yield]
[+In] RelationalExpression[In, ?Yield] in ShiftExpression[?Yield]

NOTE 2 The [In] grammar parameter is needed to avoid confusing the in operator in a relational expression with the in operator in a for statement.

12.9.1 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

RelationalExpression :
RelationalExpression < ShiftExpression
RelationalExpression > ShiftExpression
RelationalExpression <= ShiftExpression
RelationalExpression >= ShiftExpression
RelationalExpression instanceof ShiftExpression
RelationalExpression in ShiftExpression
  1. Return false.

12.9.2 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

RelationalExpression :
RelationalExpression < ShiftExpression
RelationalExpression > ShiftExpression
RelationalExpression <= ShiftExpression
RelationalExpression >= ShiftExpression
RelationalExpression instanceof ShiftExpression
RelationalExpression in ShiftExpression
  1. Return false.

12.9.3 Runtime Semantics: Evaluation

RelationalExpression : RelationalExpression < ShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating ShiftExpression.
  5. Let rval be GetValue(rref).
  6. Let r be the result of performing Abstract Relational Comparison lval < rval. (see 7.2.11)
  7. ReturnIfAbrupt(r).
  8. If r is undefined, return false. Otherwise, return r.
RelationalExpression : RelationalExpression > ShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating ShiftExpression.
  5. Let rval be GetValue(rref).
  6. Let r be the result of performing Abstract Relational Comparison rval < lval with LeftFirst equal to false.
  7. ReturnIfAbrupt(r).
  8. If r is undefined, return false. Otherwise, return r.
RelationalExpression : RelationalExpression <= ShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating ShiftExpression.
  5. Let rval be GetValue(rref).
  6. Let r be the result of performing Abstract Relational Comparison rval < lval with LeftFirst equal to false.
  7. ReturnIfAbrupt(r).
  8. If r is true or undefined, return false. Otherwise, return true.
RelationalExpression : RelationalExpression >= ShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating ShiftExpression.
  5. Let rval be GetValue(rref).
  6. Let r be the result of performing Abstract Relational Comparison lval < rval.
  7. ReturnIfAbrupt(r).
  8. If r is true or undefined, return false. Otherwise, return true.
RelationalExpression : RelationalExpression instanceof ShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating ShiftExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Return InstanceofOperator(lval, rval).
RelationalExpression : RelationalExpression in ShiftExpression
  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating ShiftExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. If Type(rval) is not Object, throw a TypeError exception.
  8. Return HasProperty(rval, ToPropertyKey(lval)).

12.9.4 Runtime Semantics: InstanceofOperator(O, C)

The abstract operation InstanceofOperator(O, C) implements the generic algorithm for determining if an object O inherits from the inheritance path defined by constructor C. This abstract operation performs the following steps:

  1. If Type(C) is not Object, throw a TypeError exception.
  2. Let instOfHandler be GetMethod(C,@@hasInstance).
  3. ReturnIfAbrupt(instOfHandler).
  4. If instOfHandler is not undefined, then
    1. Return ToBoolean(Call(instOfHandler, C, «O»)).
  5. If IsCallable(C) is false, throw a TypeError exception.
  6. Return OrdinaryHasInstance(C, O).

NOTE Steps 5 and 6 provide compatibility with previous editions of ECMAScript that did not use a @@hasInstance method to define the instanceof operator semantics. If a function object does not define or inherit @@hasInstance it uses the default instanceof semantics.

12.10 Equality Operators

NOTE The result of evaluating an equality operator is always of type Boolean, reflecting whether the relationship named by the operator holds between its two operands.

Syntax

EqualityExpression[In, Yield] :
RelationalExpression[?In, ?Yield]
EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield]
EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield]
EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield]
EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield]

12.10.1 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

EqualityExpression :
EqualityExpression == RelationalExpression
EqualityExpression != RelationalExpression
EqualityExpression === RelationalExpression
EqualityExpression !== RelationalExpression
  1. Return false.

12.10.2 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

EqualityExpression :
EqualityExpression == RelationalExpression
EqualityExpression != RelationalExpression
EqualityExpression === RelationalExpression
EqualityExpression !== RelationalExpression
  1. Return false.

12.10.3 Runtime Semantics: Evaluation

EqualityExpression : EqualityExpression == RelationalExpression
  1. Let lref be the result of evaluating EqualityExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating RelationalExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Return the result of performing Abstract Equality Comparison rval == lval.
EqualityExpression : EqualityExpression != RelationalExpression
  1. Let lref be the result of evaluating EqualityExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating RelationalExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Let r be the result of performing Abstract Equality Comparison rval == lval.
  8. If r is true, return false. Otherwise, return true.
EqualityExpression : EqualityExpression === RelationalExpression
  1. Let lref be the result of evaluating EqualityExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval)
  4. Let rref be the result of evaluating RelationalExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Return the result of performing Strict Equality Comparison rval === lval.
EqualityExpression : EqualityExpression !== RelationalExpression
  1. Let lref be the result of evaluating EqualityExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating RelationalExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Let r be the result of performing Strict Equality Comparison rval === lval.
  8. If r is true, return false. Otherwise, return true.

NOTE 1 Given the above definition of equality:

  • String comparison can be forced by: "" + a == "" + b.
  • Numeric comparison can be forced by: +a == +b.
  • Boolean comparison can be forced by: !a == !b.

NOTE 2 The equality operators maintain the following invariants:

  • A != B is equivalent to !(A == B).
  • A == B is equivalent to B == A, except in the order of evaluation of A and B.

NOTE 3 The equality operator is not always transitive. For example, there might be two distinct String objects, each representing the same String value; each String object would be considered equal to the String value by the == operator, but the two String objects would not be equal to each other. For example:

  • new String("a") == "a" and "a" == new String("a") are both true.
  • new String("a") == new String("a") is false.

NOTE 4 Comparison of Strings uses a simple equality test on sequences of code unit values. There is no attempt to use the more complex, semantically oriented definitions of character or string equality and collating order defined in the Unicode specification. Therefore Strings values that are canonically equal according to the Unicode standard could test as unequal. In effect this algorithm assumes that both Strings are already in normalized form.

12.11 Binary Bitwise Operators

Syntax

BitwiseANDExpression[In, Yield] :
EqualityExpression[?In, ?Yield]
BitwiseANDExpression[?In, ?Yield] & EqualityExpression[?In, ?Yield]
BitwiseXORExpression[In, Yield] :
BitwiseANDExpression[?In, ?Yield]
BitwiseXORExpression[?In, ?Yield] ^ BitwiseANDExpression[?In, ?Yield]
BitwiseORExpression[In, Yield] :
BitwiseXORExpression[?In, ?Yield]
BitwiseORExpression[?In, ?Yield] | BitwiseXORExpression[?In, ?Yield]

12.11.1 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.12.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

BitwiseANDExpression : BitwiseANDExpression & EqualityExpression
BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression
BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression

  1. Return false.

12.11.2 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.12.2, 12.13.2, 12.14.3, 12.15.2.

BitwiseANDExpression : BitwiseANDExpression & EqualityExpression
BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression
BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression

  1. Return false.

12.11.3 Runtime Semantics: Evaluation

The production A : A @ B, where @ is one of the bitwise operators in the productions above, is evaluated as follows:

  1. Let lref be the result of evaluating A.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating B.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Let lnum be ToInt32(lval).
  8. ReturnIfAbrupt(lnum).
  9. Let rnum be ToInt32(rval).
  10. ReturnIfAbrupt(rnum).
  11. Return the result of applying the bitwise operator @ to lnum and rnum. The result is a signed 32 bit integer.

12.12 Binary Logical Operators

Syntax

LogicalANDExpression[In, Yield] :
BitwiseORExpression[?In, ?Yield]
LogicalANDExpression[?In, ?Yield] && BitwiseORExpression[?In, ?Yield]
LogicalORExpression[In, Yield] :
LogicalANDExpression[?In, ?Yield]
LogicalORExpression[?In, ?Yield] || LogicalANDExpression[?In, ?Yield]

NOTE The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions.

12.12.1 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.13.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
LogicalORExpression : LogicalORExpression || LogicalANDExpression

  1. Return false.

12.12.2 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.13.2, 12.14.3, 12.15.2.

LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
LogicalORExpression : LogicalORExpression || LogicalANDExpression

  1. Return false.

12.12.3 Runtime Semantics: Evaluation

LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. Let lref be the result of evaluating LogicalANDExpression.
  2. Let lval be GetValue(lref).
  3. Let lbool be ToBoolean(lval).
  4. ReturnIfAbrupt(lbool).
  5. If lbool is false, return lval.
  6. Let rref be the result of evaluating BitwiseORExpression.
  7. Return GetValue(rref).
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. Let lref be the result of evaluating LogicalORExpression.
  2. Let lval be GetValue(lref).
  3. Let lbool be ToBoolean(lval).
  4. ReturnIfAbrupt(lbool).
  5. If lbool is true, return lval.
  6. Let rref be the result of evaluating LogicalANDExpression.
  7. Return GetValue(rref).

12.13 Conditional Operator ( ? : )

Syntax

ConditionalExpression[In, Yield] :
LogicalORExpression[?In, ?Yield]
LogicalORExpression[?In,?Yield] ? AssignmentExpression[In, ?Yield] : AssignmentExpression[?In, ?Yield]

NOTE The grammar for a ConditionalExpression in ECMAScript is slightly different from that in C and Java, which each allow the second subexpression to be an Expression but restrict the third expression to be a ConditionalExpression. The motivation for this difference in ECMAScript is to allow an assignment expression to be governed by either arm of a conditional and to eliminate the confusing and fairly useless case of a comma expression as the centre expression.

12.13.1 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.14.2, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

ConditionalExpression : LogicalORExpression ? AssignmentExpression : AssignmentExpression
  1. Return false.

12.13.2 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.14.3, 12.15.2.

ConditionalExpression : LogicalORExpression ? AssignmentExpression : AssignmentExpression
  1. Return false.

12.13.3 Runtime Semantics: Evaluation

ConditionalExpression : LogicalORExpression ? AssignmentExpression : AssignmentExpression
  1. Let lref be the result of evaluating LogicalORExpression.
  2. Let lval be ToBoolean(GetValue(lref)).
  3. ReturnIfAbrupt(lval).
  4. If lval is true, then
    1. Let trueRef be the result of evaluating the first AssignmentExpression.
    2. Return GetValue(trueRef).
  5. Else
    1. Let falseRef be the result of evaluating the second AssignmentExpression.
    2. Return GetValue(falseRef).

12.14 Assignment Operators

Syntax

AssignmentExpression[In, Yield] :
ConditionalExpression[?In, ?Yield]
[+Yield] YieldExpression[?In]
ArrowFunction[?In, ?Yield]
LeftHandSideExpression[?Yield] = AssignmentExpression[?In, ?Yield]
LeftHandSideExpression[?Yield] AssignmentOperator AssignmentExpression[?In, ?Yield]
AssignmentOperator : one of
*= /= %= += -= <<= >>= >>>= &= ^= |=

12.14.1 Static Semantics: Early Errors

AssignmentExpression : LeftHandSideExpression = AssignmentExpression
  • It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and the lexical token sequence matched by LeftHandSideExpression cannot be parsed with no tokens left over using AssignmentPattern as the goal symbol.

  • It is an early Reference Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget of LeftHandSideExpression is false.

AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression
  • It is an early Reference Error if IsValidSimpleAssignmentTarget of LeftHandSideExpression is false.

12.14.2 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.15.1, 14.1.11, 14.4.9, 14.5.8.

AssignmentExpression : ArrowFunction
  1. Return true.
AssignmentExpression :
YieldExpression
LeftHandSideExpression = AssignmentExpression
LeftHandSideExpression AssignmentOperator AssignmentExpression
  1. Return false.

12.14.3 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.15.2.

AssignmentExpression :
YieldExpression
ArrowFunction
LeftHandSideExpression = AssignmentExpression
LeftHandSideExpression AssignmentOperator AssignmentExpression
  1. Return false.

12.14.4 Runtime Semantics: Evaluation

AssignmentExpression[In, Yield] : LeftHandSideExpression[?Yield] = AssignmentExpression[?In, ?Yield]

  1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Let lref be the result of evaluating LeftHandSideExpression.
    2. ReturnIfAbrupt(lref).
    3. Let rref be the result of evaluating AssignmentExpression.
    4. Let rval be GetValue(rref).
    5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
      1. Let hasNameProperty be HasOwnProperty(rval, "name").
      2. ReturnIfAbrupt(hasNameProperty).
      3. If hasNameProperty is false, perform SetFunctionName(rval, GetReferencedName(lref)).
    6. Let status be PutValue(lref, rval).
    7. ReturnIfAbrupt(status).
    8. Return rval.
  2. Let assignmentPattern be the parse of the source text corresponding to LeftHandSideExpression using AssignmentPattern[?Yield] as the goal symbol.
  3. Let rref be the result of evaluating AssignmentExpression.
  4. Let rval be GetValue(rref).
  5. ReturnIfAbrupt(rval).
  6. Let status be the result of performing DestructuringAssignmentEvaluation of assignmentPattern using rval as the argument.
  7. ReturnIfAbrupt(status).
  8. Return rval.
AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression
  1. Let lref be the result of evaluating LeftHandSideExpression.
  2. Let lval be GetValue(lref).
  3. ReturnIfAbrupt(lval).
  4. Let rref be the result of evaluating AssignmentExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Let op be the @ where AssignmentOperator is @=
  8. Let r be the result of applying op to lval and rval as if evaluating the expression lval op rval.
  9. Let status be PutValue(lref, r).
  10. ReturnIfAbrupt(status).
  11. Return r.

NOTE When an assignment occurs within strict mode code, it is an runtime error if lref in step 1.f.of the first algorithm or step 9 of the second algorithm it is an unresolvable reference. If it is, a ReferenceError exception is thrown. The LeftHandSide also may not be a reference to a data property with the attribute value {[[Writable]]:false}, to an accessor property with the attribute value {[[Set]]:undefined}, nor to a non-existent property of an object for which the IsExtensible predicate returns the value false. In these cases a TypeError exception is thrown.

12.14.5 Destructuring Assignment

Supplemental Syntax

In certain circumstances when processing the production AssignmentExpression : LeftHandSideExpression = AssignmentExpression the following grammar is used to refine the interpretation of LeftHandSideExpression.

AssignmentPattern[Yield] :
ObjectAssignmentPattern[?Yield]
ArrayAssignmentPattern[?Yield]
ObjectAssignmentPattern[Yield] :
{ }
{ AssignmentPropertyList[?Yield] }
{ AssignmentPropertyList[?Yield] , }
ArrayAssignmentPattern[Yield] :
[ Elisionopt AssignmentRestElement[?Yield]opt ]
[ AssignmentElementList[?Yield] ]
[ AssignmentElementList[?Yield] , Elisionopt AssignmentRestElement[?Yield]opt ]
AssignmentPropertyList[Yield] :
AssignmentProperty[?Yield]
AssignmentPropertyList[?Yield] , AssignmentProperty[?Yield]
AssignmentElementList[Yield] :
AssignmentElisionElement[?Yield]
AssignmentElementList[?Yield] , AssignmentElisionElement[?Yield]
AssignmentElisionElement[Yield] :
Elisionopt AssignmentElement[?Yield]
AssignmentProperty[Yield] :
IdentifierReference[?Yield] Initializer[In,?Yield]opt
PropertyName : AssignmentElement[?Yield]
AssignmentElement[Yield] :
DestructuringAssignmentTarget[?Yield] Initializer[In,?Yield]opt
AssignmentRestElement[Yield] :
... DestructuringAssignmentTarget[?Yield]
DestructuringAssignmentTarget[Yield] :
LeftHandSideExpression[?Yield]

12.14.5.1 Static Semantics: Early Errors

AssignmentProperty : IdentifierReference Initializeropt
  • It is a Syntax Error if IsValidSimpleAssignmentTarget of IdentifierReference is false.

DestructuringAssignmentTarget : LeftHandSideExpression
  • It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression cannot be parsed with no tokens left over using AssignmentPattern as the goal symbol.

  • It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is false.

12.14.5.2 Runtime Semantics: DestructuringAssignmentEvaluation

with parameter value

ObjectAssignmentPattern : { }
  1. Let valid be RequireObjectCoercible(value).
  2. ReturnIfAbrupt(valid).
  3. Return NormalCompletion(empty).
ObjectAssignmentPattern :
{ AssignmentPropertyList }
{ AssignmentPropertyList , }
  1. Let valid be RequireObjectCoercible(value).
  2. ReturnIfAbrupt(valid).
  3. Return the result of performing DestructuringAssignmentEvaluation for AssignmentPropertyList using value as the argument.
ArrayAssignmentPattern : [ ]
  1. Let iterator be GetIterator(val ue).
  2. ReturnIfAbrupt(iterator).
  3. Return IteratorClose(iterator, NormalCompletion(empty)).
ArrayAssignmentPattern : [ Elision ]
  1. Let iterator be GetIterator(value).
  2. ReturnIfAbrupt(iterator).
  3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
  4. Let result be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
  5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
  6. Return result.
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
  1. Let iterator be GetIterator(value).
  2. ReturnIfAbrupt(iterator).
  3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
  4. If Elision is present, then
    1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
    2. If status is an abrupt completion, then
      1. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, status).
      2. Return Completion(status).
  5. Let result be the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with iteratorRecord as the argument.
  6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
  7. Return result.
ArrayAssignmentPattern : [ AssignmentElementList ]
  1. Let iterator be GetIterator(value).
  2. ReturnIfAbrupt(iterator).
  3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
  4. Let result be the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElementList using iteratorRecord as the argument.
  5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
  6. Return result.
ArrayAssignmentPattern : [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
  1. Let iterator be GetIterator(value).
  2. ReturnIfAbrupt(iterator).
  3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
  4. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElementList using iteratorRecord as the argument.
  5. If status is an abrupt completion, then
    1. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, status).
    2. Return Completion(status).
  6. If Elision is present, then
    1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
    2. If status is an abrupt completion, then
      1. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, status).
      2. Return Completion(status).
  7. If AssignmentRestElement is present, then
    1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with iteratorRecord as the argument.
  8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, status).
  9. Return Completion(status).
AssignmentPropertyList : AssignmentPropertyList , AssignmentProperty
  1. Let status be the result of performing DestructuringAssignmentEvaluation for AssignmentPropertyList using value as the argument.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing DestructuringAssignmentEvaluation for AssignmentProperty using value as the argument.
AssignmentProperty : IdentifierReference Initializeropt
  1. Let P be StringValue of IdentifierReference.
  2. Let lref be ResolveBinding(P).
  3. ReturnIfAbrupt(P).
  4. Let v be GetV(value, P).
  5. ReturnIfAbrupt(v).
  6. If Initializeropt is present and v is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Let v be GetValue(defaultValue).
    3. ReturnIfAbrupt(v).
    4. If IsAnonymousFunctionDefinition(Initializer) is true, then
      1. Let hasNameProperty be HasOwnProperty(v, "name").
      2. ReturnIfAbrupt(hasNameProperty).
      3. If hasNameProperty is false, perform SetFunctionName(v, P).
  7. Return PutValue(lref,v).
AssignmentProperty : PropertyName : AssignmentElement
  1. Let name be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(name).
  3. Return the result of performing KeyedDestructuringAssignmentEvaluation of AssignmentElement with value and name as the arguments.

12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation

with parameters iteratorRecord

AssignmentElementList : AssignmentElisionElement
  1. Return the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElisionElement using iteratorRecord as the argument.
AssignmentElementList : AssignmentElementList , AssignmentElisionElement
  1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElementList using iteratorRecord as the argument.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElisionElement using iteratorRecord as the argument.
AssignmentElisionElement : AssignmentElement
  1. Return the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElement with iteratorRecord as the argument.
AssignmentElisionElement : Elision AssignmentElement
  1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
  2. ReturnIfAbrupt(status).
  3. Return the result of performing IteratorDestructuringAssignmentEvaluation of AssignmentElement with iteratorRecord as the argument.
Elision : ,
  1. If iteratorRecord.[[done]] is false, then
    1. Let next be IteratorStep(iteratorRecord.[[iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, set iteratorRecord.[[done]] to true.
  2. Return NormalCompletion(empty).
Elision : Elision ,
  1. Let status be the result of performing IteratorDestructuringAssignmentEvaluation of Elision with iteratorRecord as the argument.
  2. ReturnIfAbrupt(status).
  3. If iteratorRecord.[[done]] is false, then
    1. Let next be IteratorStep(iteratorRecord.[[iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, set iteratorRecord.[[done]] to true.
  4. Return NormalCompletion(empty).

AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt

  1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Let lref be the result of evaluating DestructuringAssignmentTarget.
    2. ReturnIfAbrupt(lref).
  2. If iteratorRecord.[[done]] is false, then
    1. Let next be IteratorStep(iteratorRecord.[[iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, set iteratorRecord.[[done]] to true.
    5. Else
      1. Let value be IteratorValue(next).
      2. If value is an abrupt completion, set iteratorRecord.[[done]] to true.
      3. ReturnIfAbrupt(value).
  3. If iteratorRecord.[[done]] is true, let value be undefined.
  4. If Initializer is present and value is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Let v be GetValue(defaultValue)
    3. ReturnIfAbrupt(v).
  5. Else, let v be value.
  6. If DestructuringAssignmentTarget is an ObjectLiteral or an ArrayLiteral, then
    1. Let nestedAssignmentPattern be the parse of the source text corresponding to DestructuringAssignmentTarget using either AssignmentPattern or AssignmentPattern[Yield] as the goal symbol depending upon whether this AssignmentElement has the Yield parameter.
    2. Return the result of performing DestructuringAssignmentEvaluation of nestedAssignmentPattern with v as the argument.
  7. If Initializer is present and value is undefined and IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of DestructuringAssignmentTarget are both true, then
    1. Let hasNameProperty be HasOwnProperty(v, "name").
    2. ReturnIfAbrupt(hasNameProperty).
    3. If hasNameProperty is false, perform SetFunctionName(v, GetReferencedName(lref)).
  8. Return PutValue(lref, v).

NOTE Left to right evaluation order is maintained by evaluating a DestructuringAssignmentTarget that is not a destructuring pattern prior to accessing the iterator or evaluating the Initializer.

AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget

  1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Let lref be the result of evaluating DestructuringAssignmentTarget.
    2. ReturnIfAbrupt(lref).
  2. Let A be ArrayCreate(0).
  3. Let n=0;
  4. Repeat while iteratorRecord.[[done]] is false,
    1. Let next be IteratorStep(iteratorRecord.[[iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, set iteratorRecord.[[done]] to true.
    5. else,
      1. Let nextValue be IteratorValue(next).
      2. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to true.
      3. ReturnIfAbrupt(nextValue).
      4. Let status be CreateDataProperty(A, ToString(n), nextValue).
      5. Assert: status is true.
      6. Increment n by 1.
  5. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Return PutValue(lref, A).
  6. Let nestedAssignmentPattern be the parse of the source text corresponding to DestructuringAssignmentTarget using either AssignmentPattern or AssignmentPattern[Yield] as the goal symbol depending upon whether this AssignmentElement has the Yield parameter.
  7. Return the result of performing DestructuringAssignmentEvaluation of nestedAssignmentPattern with A as the argument.

12.14.5.4 Runtime Semantics: KeyedDestructuringAssignmentEvaluation

with parameters value and propertyName

AssignmentElement[Yield] : DestructuringAssignmentTarget Initializeropt

  1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Let lref be the result of evaluating DestructuringAssignmentTarget.
    2. ReturnIfAbrupt(lref).
  2. Let v be GetV(value, propertyName).
  3. ReturnIfAbrupt(v).
  4. If Initializer is present and v is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Let rhsValue be GetValue(defaultValue)
    3. ReturnIfAbrupt(rhsValue).
  5. Else, let rhsValue be v.
  6. If DestructuringAssignmentTarget is an ObjectLiteral or an ArrayLiteral, then
    1. Let assignmentPattern be the parse of the source text corresponding to DestructuringAssignmentTarget using either AssignmentPattern or AssignmentPattern[Yield] as the goal symbol depending upon whether this AssignmentElement has the Yield parameter.
    2. Return the result of performing DestructuringAssignmentEvaluation of assignmentPattern with rhsValue as the argument.
  7. If Initializer is present and v is undefined and IsAnonymousFunctionDefinition(Initializer) and IsIdentifierRef of DestructuringAssignmentTarget are both true, then
    1. Let hasNameProperty be HasOwnProperty(rhsValue, "name").
    2. ReturnIfAbrupt(hasNameProperty).
    3. If hasNameProperty is false, perform SetFunctionName(rhsValue, GetReferencedName(lref)).
  8. Return PutValue(lref, rhsValue).

12.15 Comma Operator ( , )

Syntax

Expression[In, Yield] :
AssignmentExpression[?In, ?Yield]
Expression[?In, ?Yield] , AssignmentExpression[?In, ?Yield]

12.15.1 Static Semantics: IsFunctionDefinition

See also: 12.2.1.3, 12.2.10.2, 12.3.1.2, 12.4.2, 12.5.2, 12.6.1, 12.7.1, 12.8.1, 12.9.1, 12.10.1, 12.11.1, 12.12.1, 12.13.1, 12.14.2, 14.1.11, 14.4.9, 14.5.8.

Expression : Expression , AssignmentExpression
  1. Return false.

12.15.2 Static Semantics: IsValidSimpleAssignmentTarget

See also: 12.1.3, 12.2.1.5, 12.2.10.3, 12.3.1.5, 12.4.3, 12.5.3, 12.6.2, 12.7.2, 12.8.2, 12.9.2, 12.10.2, 12.11.2, 12.12.2, 12.13.2, 12.14.3.

Expression : Expression , AssignmentExpression
  1. Return false.

12.15.3 Runtime Semantics: Evaluation

Expression : Expression , AssignmentExpression
  1. Let lref be the result of evaluating Expression.
  2. ReturnIfAbrupt(GetValue(lref))
  3. Let rref be the result of evaluating AssignmentExpression.
  4. Return GetValue(rref).

NOTE GetValue must be called even though its value is not used because it may have observable side-effects.