13.2 Primary Expression

Syntax

PrimaryExpression[Yield, Await] : this IdentifierReference[?Yield, ?Await] Literal ArrayLiteral[?Yield, ?Await] ObjectLiteral[?Yield, ?Await] FunctionExpression ClassExpression[?Yield, ?Await] GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral[?Yield, ?Await, ~Tagged] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[Yield, Await] : ( Expression[+In, ?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ) ( ) ( ... BindingIdentifier[?Yield, ?Await] ) ( ... BindingPattern[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingIdentifier[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingPattern[?Yield, ?Await] )

Supplemental Syntax

When processing an instance of the production
PrimaryExpression[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
the interpretation of CoverParenthesizedExpressionAndArrowParameterList is refined using the following grammar:

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

13.2.1 Semantics

13.2.1.1 Static Semantics: CoveredParenthesizedExpression

CoverParenthesizedExpressionAndArrowParameterList : ( Expression )
  1. Return the ParenthesizedExpression that is covered by CoverParenthesizedExpressionAndArrowParameterList.

13.2.2 The this Keyword

13.2.2.1 Runtime Semantics: Evaluation

PrimaryExpression : this
  1. Return ? ResolveThisBinding().

13.2.3 Identifier Reference

See 13.1 for IdentifierReference.

13.2.4 Literals

Syntax

Literal : NullLiteral BooleanLiteral NumericLiteral StringLiteral

13.2.4.1 Runtime Semantics: Evaluation

Literal : NullLiteral
  1. Return null.
Literal : BooleanLiteral
  1. If BooleanLiteral is the token false, return false.
  2. If BooleanLiteral is the token true, return true.
Literal : NumericLiteral
  1. Return the NumericValue of NumericLiteral as defined in 12.8.3.
Literal : StringLiteral
  1. Return the SV of StringLiteral as defined in 12.8.4.1.

13.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, Await] : [ Elisionopt ] [ ElementList[?Yield, ?Await] ] [ ElementList[?Yield, ?Await] , Elisionopt ] ElementList[Yield, Await] : Elisionopt AssignmentExpression[+In, ?Yield, ?Await] Elisionopt SpreadElement[?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt AssignmentExpression[+In, ?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt SpreadElement[?Yield, ?Await] Elision : , Elision , SpreadElement[Yield, Await] : ... AssignmentExpression[+In, ?Yield, ?Await]

13.2.5.1 Runtime Semantics: ArrayAccumulation

With parameters array and nextIndex.

Elision : ,
  1. Let len be nextIndex + 1.
  2. Perform ? Set(array, "length", 𝔽(len), true).
  3. NOTE: The above Set throws if len exceeds 232-1.
  4. Return len.
Elision : Elision ,
  1. Return the result of performing ArrayAccumulation for Elision with arguments array and nextIndex + 1.
ElementList : Elisionopt AssignmentExpression
  1. If Elision is present, then
    1. Set nextIndex to the result of performing ArrayAccumulation for Elision with arguments array and nextIndex.
    2. ReturnIfAbrupt(nextIndex).
  2. Let initResult be the result of evaluating AssignmentExpression.
  3. Let initValue be ? GetValue(initResult).
  4. Let created be ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue).
  5. Return nextIndex + 1.
ElementList : Elisionopt SpreadElement
  1. If Elision is present, then
    1. Set nextIndex to the result of performing ArrayAccumulation for Elision with arguments array and nextIndex.
    2. ReturnIfAbrupt(nextIndex).
  2. Return the result of performing ArrayAccumulation for SpreadElement with arguments array and nextIndex.
ElementList : ElementList , Elisionopt AssignmentExpression
  1. Set nextIndex to the result of performing ArrayAccumulation for ElementList with arguments array and nextIndex.
  2. ReturnIfAbrupt(nextIndex).
  3. If Elision is present, then
    1. Set nextIndex to the result of performing ArrayAccumulation for Elision with arguments array and nextIndex.
    2. ReturnIfAbrupt(nextIndex).
  4. Let initResult be the result of evaluating AssignmentExpression.
  5. Let initValue be ? GetValue(initResult).
  6. Let created be ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue).
  7. Return nextIndex + 1.
ElementList : ElementList , Elisionopt SpreadElement
  1. Set nextIndex to the result of performing ArrayAccumulation for ElementList with arguments array and nextIndex.
  2. ReturnIfAbrupt(nextIndex).
  3. If Elision is present, then
    1. Set nextIndex to the result of performing ArrayAccumulation for Elision with arguments array and nextIndex.
    2. ReturnIfAbrupt(nextIndex).
  4. Return the result of performing ArrayAccumulation for SpreadElement with arguments array and nextIndex.
SpreadElement : ... AssignmentExpression
  1. Let spreadRef be the result of evaluating AssignmentExpression.
  2. Let spreadObj be ? GetValue(spreadRef).
  3. Let iteratorRecord be ? GetIterator(spreadObj).
  4. Repeat,
    1. Let next be ? IteratorStep(iteratorRecord).
    2. If next is false, return nextIndex.
    3. Let nextValue be ? IteratorValue(next).
    4. Perform ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), nextValue).
    5. Set nextIndex to nextIndex + 1.
Note

CreateDataPropertyOrThrow 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]].

13.2.5.2 Runtime Semantics: Evaluation

ArrayLiteral : [ Elisionopt ]
  1. Let array be ! ArrayCreate(0).
  2. If Elision is present, then
    1. Let len be the result of performing ArrayAccumulation for Elision with arguments array and 0.
    2. ReturnIfAbrupt(len).
  3. 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. Return array.
ArrayLiteral : [ ElementList , Elisionopt ]
  1. Let array be ! ArrayCreate(0).
  2. Let nextIndex be the result of performing ArrayAccumulation for ElementList with arguments array and 0.
  3. ReturnIfAbrupt(nextIndex).
  4. If Elision is present, then
    1. Let len be the result of performing ArrayAccumulation for Elision with arguments array and nextIndex.
    2. ReturnIfAbrupt(len).
  5. Return array.

13.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, Await] : { } { PropertyDefinitionList[?Yield, ?Await] } { PropertyDefinitionList[?Yield, ?Await] , } PropertyDefinitionList[Yield, Await] : PropertyDefinition[?Yield, ?Await] PropertyDefinitionList[?Yield, ?Await] , PropertyDefinition[?Yield, ?Await] PropertyDefinition[Yield, Await] : IdentifierReference[?Yield, ?Await] CoverInitializedName[?Yield, ?Await] PropertyName[?Yield, ?Await] : AssignmentExpression[+In, ?Yield, ?Await] MethodDefinition[?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] PropertyName[Yield, Await] : LiteralPropertyName ComputedPropertyName[?Yield, ?Await] LiteralPropertyName : IdentifierName StringLiteral NumericLiteral ComputedPropertyName[Yield, Await] : [ AssignmentExpression[+In, ?Yield, ?Await] ] CoverInitializedName[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await] Initializer[In, Yield, Await] : = AssignmentExpression[?In, ?Yield, ?Await] Note 2

MethodDefinition is defined in 15.4.

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.

13.2.6.1 Static Semantics: Early Errors

PropertyDefinition : MethodDefinition

In addition to describing an actual object initializer the ObjectLiteral productions are also used as a cover grammar for ObjectAssignmentPattern 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 or CoverCallExpressionAndAsyncArrowHead.

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. It cannot occur in an actual object initializer.

13.2.6.2 Static Semantics: IsComputedPropertyKey

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

13.2.6.3 Static Semantics: PropertyNameList

PropertyDefinitionList : PropertyDefinition
  1. If PropName of PropertyDefinition is empty, return a new empty List.
  2. Return a List whose sole element is 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.

13.2.6.4 Runtime Semantics: Evaluation

ObjectLiteral : { }
  1. Return ! OrdinaryObjectCreate(%Object.prototype%).
ObjectLiteral : { PropertyDefinitionList } { PropertyDefinitionList , }
  1. Let obj be ! OrdinaryObjectCreate(%Object.prototype%).
  2. Perform ? PropertyDefinitionEvaluation of PropertyDefinitionList with arguments obj and true.
  3. Return obj.
LiteralPropertyName : IdentifierName
  1. Return StringValue of IdentifierName.
LiteralPropertyName : StringLiteral
  1. Return the SV of StringLiteral.
LiteralPropertyName : NumericLiteral
  1. Let nbr be the NumericValue of NumericLiteral.
  2. Return ! ToString(nbr).
ComputedPropertyName : [ AssignmentExpression ]
  1. Let exprValue be the result of evaluating AssignmentExpression.
  2. Let propName be ? GetValue(exprValue).
  3. Return ? ToPropertyKey(propName).

13.2.6.5 Runtime Semantics: PropertyDefinitionEvaluation

With parameters object and enumerable.

PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. Perform ? PropertyDefinitionEvaluation of PropertyDefinitionList with arguments object and enumerable.
  2. Return the result of performing PropertyDefinitionEvaluation of PropertyDefinition with arguments object and enumerable.
PropertyDefinition : ... AssignmentExpression
  1. Let exprValue be the result of evaluating AssignmentExpression.
  2. Let fromValue be ? GetValue(exprValue).
  3. Let excludedNames be a new empty List.
  4. Return ? CopyDataProperties(object, fromValue, excludedNames).
PropertyDefinition : IdentifierReference
  1. Let propName be StringValue of IdentifierReference.
  2. Let exprValue be the result of evaluating IdentifierReference.
  3. Let propValue be ? GetValue(exprValue).
  4. Assert: enumerable is true.
  5. Assert: object is an ordinary, extensible object with no non-configurable properties.
  6. Return ! CreateDataPropertyOrThrow(object, propName, propValue).
PropertyDefinition : PropertyName : AssignmentExpression
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let propValue be ? NamedEvaluation of AssignmentExpression with argument propKey.
  4. Else,
    1. Let exprValueRef be the result of evaluating AssignmentExpression.
    2. Let propValue be ? GetValue(exprValueRef).
  5. Assert: enumerable is true.
  6. Assert: object is an ordinary, extensible object with no non-configurable properties.
  7. Return ! CreateDataPropertyOrThrow(object, propKey, propValue).
Note

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

MethodDefinition : PropertyName ( UniqueFormalParameters ) { FunctionBody } get PropertyName ( ) { FunctionBody } set PropertyName ( PropertySetParameterList ) { FunctionBody }
  1. Return ? MethodDefinitionEvaluation of MethodDefinition with arguments object and enumerable.
GeneratorMethod : * PropertyName ( UniqueFormalParameters ) { GeneratorBody }
  1. Return ? MethodDefinitionEvaluation of GeneratorMethod with arguments object and enumerable.
AsyncGeneratorMethod : async * PropertyName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. Return ? MethodDefinitionEvaluation of AsyncGeneratorMethod with arguments object and enumerable.
AsyncMethod : async PropertyName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. Return ? MethodDefinitionEvaluation of AsyncMethod with arguments object and enumerable.

13.2.7 Function Defining Expressions

See 15.2 for PrimaryExpression : FunctionExpression .

See 15.5 for PrimaryExpression : GeneratorExpression .

See 15.7 for PrimaryExpression : ClassExpression .

See 15.8 for PrimaryExpression : AsyncFunctionExpression .

See 15.6 for PrimaryExpression : AsyncGeneratorExpression .

13.2.8 Regular Expression Literals

Syntax

See 12.8.5.

13.2.8.1 Static Semantics: Early Errors

PrimaryExpression : RegularExpressionLiteral

13.2.8.2 Static Semantics: IsValidRegularExpressionLiteral ( literal )

The abstract operation IsValidRegularExpressionLiteral takes argument literal. It determines if its argument is a valid regular expression literal. It performs the following steps when called:

  1. Assert: literal is a RegularExpressionLiteral.
  2. If FlagText of literal contains any code points other than g, i, m, s, u, or y, or if it contains the same code point more than once, return false.
  3. Let patternText be BodyText of literal.
  4. If FlagText of literal contains u, let u be true; else let u be false.
  5. If u is false, then
    1. Let stringValue be CodePointsToString(patternText).
    2. Set patternText to the sequence of code points resulting from interpreting each of the 16-bit elements of stringValue as a Unicode BMP code point. UTF-16 decoding is not applied to the elements.
  6. Let parseResult be ParsePattern(patternText, u).
  7. If parseResult is a Parse Node, return true; else return false.

13.2.8.3 Runtime Semantics: Evaluation

PrimaryExpression : RegularExpressionLiteral
  1. Let pattern be ! CodePointsToString(BodyText of RegularExpressionLiteral).
  2. Let flags be ! CodePointsToString(FlagText of RegularExpressionLiteral).
  3. Return RegExpCreate(pattern, flags).

13.2.9 Template Literals

Syntax

TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate SubstitutionTemplate[?Yield, ?Await, ?Tagged] SubstitutionTemplate[Yield, Await, Tagged] : TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged] TemplateSpans[Yield, Await, Tagged] : TemplateTail TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateTail TemplateMiddleList[Yield, Await, Tagged] : TemplateMiddle Expression[+In, ?Yield, ?Await] TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await]

13.2.9.1 Static Semantics: Early Errors

TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate TemplateLiteral[Yield, Await, Tagged] : SubstitutionTemplate[?Yield, ?Await, ?Tagged] SubstitutionTemplate[Yield, Await, Tagged] : TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged] TemplateSpans[Yield, Await, Tagged] : TemplateTail TemplateMiddleList[Yield, Await, Tagged] : TemplateMiddle Expression[+In, ?Yield, ?Await] TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await]

13.2.9.2 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 whose sole element is string.
SubstitutionTemplate : 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 whose elements are head followed by the elements 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 whose sole element is 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 whose elements are the elements 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 whose sole element is 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.

13.2.9.3 GetTemplateObject ( templateLiteral )

The abstract operation GetTemplateObject takes argument templateLiteral (a Parse Node). It performs the following steps when called:

  1. Let realm be the current Realm Record.
  2. Let templateRegistry be realm.[[TemplateMap]].
  3. For each element e of templateRegistry, do
    1. If e.[[Site]] is the same Parse Node as templateLiteral, then
      1. Return e.[[Array]].
  4. Let rawStrings be TemplateStrings of templateLiteral with argument true.
  5. Let cookedStrings be TemplateStrings of templateLiteral with argument false.
  6. Let count be the number of elements in the List cookedStrings.
  7. Assert: count ≤ 232 - 1.
  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 cookedStrings[index].
    3. Perform ! DefinePropertyOrThrow(template, prop, PropertyDescriptor { [[Value]]: cookedValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }).
    4. Let rawValue be the String value rawStrings[index].
    5. Perform ! DefinePropertyOrThrow(rawObj, prop, PropertyDescriptor { [[Value]]: rawValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }).
    6. Set index to index + 1.
  12. Perform ! SetIntegrityLevel(rawObj, frozen).
  13. Perform ! DefinePropertyOrThrow(template, "raw", PropertyDescriptor { [[Value]]: rawObj, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }).
  14. Perform ! SetIntegrityLevel(template, frozen).
  15. Append the Record { [[Site]]: templateLiteral, [[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 (13.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.

13.2.9.4 Runtime Semantics: SubstitutionEvaluation

TemplateSpans : TemplateTail
  1. Return a new empty List.
TemplateSpans : TemplateMiddleList TemplateTail
  1. Return the result of SubstitutionEvaluation of TemplateMiddleList.
TemplateMiddleList : TemplateMiddle Expression
  1. Let subRef be the result of evaluating Expression.
  2. Let sub be ? GetValue(subRef).
  3. Return a List whose sole element is sub.
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. Let preceding be ? SubstitutionEvaluation of TemplateMiddleList.
  2. Let nextRef be the result of evaluating Expression.
  3. Let next be ? GetValue(nextRef).
  4. Append next as the last element of the List preceding.
  5. Return preceding.

13.2.9.5 Runtime Semantics: Evaluation

TemplateLiteral : NoSubstitutionTemplate
  1. Return the TV of NoSubstitutionTemplate as defined in 12.8.6.
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. Let head be the TV of TemplateHead as defined in 12.8.6.
  2. Let subRef be the result of evaluating Expression.
  3. Let sub be ? GetValue(subRef).
  4. Let middle be ? ToString(sub).
  5. Let tail be the result of evaluating TemplateSpans.
  6. ReturnIfAbrupt(tail).
  7. Return the string-concatenation of head, middle, and tail.
Note 1

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

TemplateSpans : TemplateTail
  1. Return the TV of TemplateTail as defined in 12.8.6.
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 12.8.6.
  4. Return the string-concatenation of head and tail.
TemplateMiddleList : TemplateMiddle Expression
  1. Let head be the TV of TemplateMiddle as defined in 12.8.6.
  2. Let subRef be the result of evaluating Expression.
  3. Let sub be ? GetValue(subRef).
  4. Let middle be ? ToString(sub).
  5. Return the string-concatenation of head and 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 12.8.6.
  4. Let subRef be the result of evaluating Expression.
  5. Let sub be ? GetValue(subRef).
  6. Let last be ? ToString(sub).
  7. Return the string-concatenation of rest, middle, and last.
Note 3

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

13.2.10 The Grouping Operator

13.2.10.1 Static Semantics: Early Errors

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList

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