13 ECMAScript 语言:表达式

13.1 标识符

语法

IdentifierReference[Yield, Await] : Identifier [~Yield] yield [~Await] await BindingIdentifier[Yield, Await] : Identifier yield await LabelIdentifier[Yield, Await] : Identifier [~Yield] yield [~Await] await Identifier : IdentifierName but not ReservedWord Note

语法中允许 yieldawait 作为 BindingIdentifier,并通过下面的静态语义禁止它们,以便在如下情形中禁止自动分号插入

let
await 0;

13.1.1 Static Semantics: 早期错误

BindingIdentifier : Identifier IdentifierReference : yield BindingIdentifier : yield LabelIdentifier : yield
  • 如果 IsStrict(this production) 是 true,则为语法错误。
IdentifierReference : await BindingIdentifier : await LabelIdentifier : await BindingIdentifier[Yield, Await] : yield
  • 如果此产生式具有 [Yield] 参数,则为语法错误。
BindingIdentifier[Yield, Await] : await
  • 如果此产生式具有 [Await] 参数,则为语法错误。
IdentifierReference[Yield, Await] : Identifier BindingIdentifier[Yield, Await] : Identifier LabelIdentifier[Yield, Await] : Identifier
  • 如果此产生式具有 [Yield] 参数,且 IdentifierStringValue"yield",则为语法错误。
  • 如果此产生式具有 [Await] 参数,且 IdentifierStringValue"await",则为语法错误。
Identifier : IdentifierName but not ReservedWord Note

IdentifierNameStringValue 会规范化 IdentifierName 中的任何 Unicode 转义序列,因此这种转义不能用于写出码点序列与 ReservedWord 相同的 Identifier

13.1.2 Static Semantics: StringValue

The syntax-directed operation StringValue takes no arguments and returns a String. It is defined piecewise over the following productions:

IdentifierName :: IdentifierStart IdentifierName IdentifierPart
  1. idTextUnescapedIdentifierNameIdentifierCodePoints
  2. 返回 CodePointsToString(idTextUnescaped)。
IdentifierReference : yield BindingIdentifier : yield LabelIdentifier : yield
  1. 返回 "yield"
IdentifierReference : await BindingIdentifier : await LabelIdentifier : await
  1. 返回 "await"
Identifier : IdentifierName but not ReservedWord
  1. 返回 IdentifierNameStringValue
PrivateIdentifier :: # IdentifierName
  1. 返回 0x0023 (NUMBER SIGN) 和 IdentifierNameStringValue字符串连接
ModuleExportName : StringLiteral
  1. 返回 StringLiteralSV

13.1.3 Runtime Semantics: Evaluation

IdentifierReference : Identifier
  1. 返回 ? ResolveBinding(IdentifierStringValue)。
IdentifierReference : yield
  1. 返回 ? ResolveBinding("yield")。
IdentifierReference : await
  1. 返回 ? ResolveBinding("await")。
Note 1

求值 IdentifierReference 的结果始终是 Reference 类型的值。

Note 2

在非严格代码中,关键字 yield 可以用作标识符。求值 IdentifierReference 会像它是 Identifier 一样解析 yield 的绑定。早期错误限制确保这种求值只能发生在非严格代码中。

13.2 主表达式

语法

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] )

补充语法

当处理产生式的实例
PrimaryExpression[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
时,使用以下语法细化 CoverParenthesizedExpressionAndArrowParameterList 的解释:

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

13.2.1 this 关键字

13.2.1.1 Runtime Semantics: Evaluation

PrimaryExpression : this
  1. 返回 ? ResolveThisBinding()。

13.2.2 标识符引用

关于 IdentifierReference,参见 13.1

13.2.3 字面量

语法

Literal : NullLiteral BooleanLiteral NumericLiteral StringLiteral

13.2.3.1 Runtime Semantics: Evaluation

Literal : NullLiteral
  1. 返回 null
Literal : BooleanLiteral
  1. 如果 BooleanLiteral 是 token false,则返回 false
  2. 如果 BooleanLiteral 是 token true,则返回 true
Literal : NumericLiteral
  1. 返回 12.9.3 中定义的 NumericLiteralNumericValue
Literal : StringLiteral
  1. 返回 12.9.4.2 中定义的 StringLiteralSV

13.2.4 数组初始化器

Note

ArrayLiteral 是描述 Array 初始化的表达式,它使用由方括号包围的列表,列表中包含零个或多个表达式,每个表达式表示一个数组元素。这些元素不必是字面量;每次求值数组初始化器时都会求值它们。

数组元素可以在元素列表的开头、中间或结尾被省略。每当元素列表中的逗号前面没有 AssignmentExpression(即开头处的逗号或另一个逗号之后的逗号)时,缺失的数组元素会计入 Array 的长度,并增加后续元素的索引。被省略的数组元素不会被定义。如果数组末尾省略了一个元素,则该元素不会计入 Array 的长度。

语法

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.4.1 Runtime Semantics: ArrayAccumulation

The syntax-directed operation ArrayAccumulation takes arguments array (an Array) and nextIndex (an integer) and returns either a normal completion containing an integer or an abrupt completion. It is defined piecewise over the following productions:

Elision : ,
  1. lengthnextIndex + 1。
  2. 执行 ? Set(array, "length", 𝔽(length), true)。
  3. 注:如果 length 超过 232 - 1,则上一步会抛出异常。
  4. 返回 length
Elision : Elision ,
  1. 返回以 array 和 (nextIndex + 1) 为实参执行 ElisionArrayAccumulation 的结果。
ElementList : Elisionopt AssignmentExpression
  1. 如果存在 Elision,则
    1. nextIndex 设置为以 arraynextIndex 为实参执行 ElisionArrayAccumulation 的结果。
  2. initResult 为 ? AssignmentExpressionEvaluation
  3. initValue 为 ? GetValue(initResult)。
  4. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue)。
  5. 返回 nextIndex + 1。
ElementList : Elisionopt SpreadElement
  1. 如果存在 Elision,则
    1. nextIndex 设置为以 arraynextIndex 为实参执行 ElisionArrayAccumulation 的结果。
  2. 返回以 arraynextIndex 为实参执行 SpreadElementArrayAccumulation 的结果。
ElementList : ElementList , Elisionopt AssignmentExpression
  1. nextIndex 设置为以 arraynextIndex 为实参执行派生的 ElementListArrayAccumulation 的结果。
  2. 如果存在 Elision,则
    1. nextIndex 设置为以 arraynextIndex 为实参执行 ElisionArrayAccumulation 的结果。
  3. initResult 为 ? AssignmentExpressionEvaluation
  4. initValue 为 ? GetValue(initResult)。
  5. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue)。
  6. 返回 nextIndex + 1。
ElementList : ElementList , Elisionopt SpreadElement
  1. nextIndex 设置为以 arraynextIndex 为实参执行派生的 ElementListArrayAccumulation 的结果。
  2. 如果存在 Elision,则
    1. nextIndex 设置为以 arraynextIndex 为实参执行 ElisionArrayAccumulation 的结果。
  3. 返回以 arraynextIndex 为实参执行 SpreadElementArrayAccumulation 的结果。
SpreadElement : ... AssignmentExpression
  1. spreadRef 为 ? AssignmentExpressionEvaluation
  2. spreadObj 为 ? GetValue(spreadRef)。
  3. iteratorRecord 为 ? GetIterator(spreadObj, sync)。
  4. 重复:
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,则返回 nextIndex
    3. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), next)。
    4. nextIndex 设置为 nextIndex + 1。
Note

使用 CreateDataPropertyOrThrow 是为了确保即使标准内置 Array prototype 对象已被以某种会妨碍使用 [[Set]] 创建新自有属性的方式修改,也会为该数组定义自有属性。

13.2.4.2 Runtime Semantics: Evaluation

ArrayLiteral : [ Elisionopt ]
  1. array 为 ! ArrayCreate(0)。
  2. 如果存在 Elision,则
    1. 执行 ? 以 array 和 0 为实参执行 ElisionArrayAccumulation
  3. 返回 array
ArrayLiteral : [ ElementList ]
  1. array 为 ! ArrayCreate(0)。
  2. 执行 ? 以 array 和 0 为实参执行 ElementListArrayAccumulation
  3. 返回 array
ArrayLiteral : [ ElementList , Elisionopt ]
  1. array 为 ! ArrayCreate(0)。
  2. nextIndex 为 ? 以 array 和 0 为实参执行 ElementListArrayAccumulation
  3. 如果存在 Elision,则
    1. 执行 ? 以 arraynextIndex 为实参执行 ElisionArrayAccumulation
  4. 返回 array

13.2.5 对象初始化器

Note 1

对象初始化器是描述 Object 初始化的表达式,它以类似字面量的形式编写。它是由花括号包围的、零个或多个属性键及其关联值的配对列表。这些值不必是字面量;每次求值对象初始化器时都会求值它们。

语法

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

MethodDefinition15.4 中定义。

Note 3

在某些上下文中,ObjectLiteral 被用作更受限的次级语法的覆盖语法。CoverInitializedName 产生式是完整覆盖这些次级语法所必需的。不过,在期望实际 ObjectLiteral 的正常上下文中,使用此产生式会导致早期语法错误。

13.2.5.1 Static Semantics: 早期错误

PropertyDefinition : MethodDefinition

除了描述实际对象初始化器之外,ObjectLiteral 产生式还被用作 ObjectAssignmentPattern 的覆盖语法,并且可能作为 CoverParenthesizedExpressionAndArrowParameterList 的一部分被识别。当 ObjectLiteral 出现在需要 ObjectAssignmentPattern 的上下文中时,不会应用以下早期错误规则。此外,在初始解析 CoverParenthesizedExpressionAndArrowParameterListCoverCallExpressionAndAsyncArrowHead 时,也不会应用这些规则。

PropertyDefinition : CoverInitializedName
  • 如果此产生式匹配到任何源文本,则为语法错误。
Note 1

此产生式存在是为了让 ObjectLiteral 可作为 ObjectAssignmentPattern 的覆盖语法。它不能出现在实际的对象初始化器中。

ObjectLiteral : { PropertyDefinitionList } { PropertyDefinitionList , } Note 2

PropertyNameList 返回的 List包含使用 ComputedPropertyName 定义的属性名

13.2.5.2 Static Semantics: IsComputedPropertyKey

The syntax-directed operation IsComputedPropertyKey takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

PropertyName : LiteralPropertyName
  1. 返回 false
PropertyName : ComputedPropertyName
  1. 返回 true

13.2.5.3 Static Semantics: PropertyDefinitionNodes

The syntax-directed operation PropertyDefinitionNodes takes no arguments and returns a List of Parse Nodes. It is defined piecewise over the following productions:

ObjectLiteral : { }
  1. 返回一个新的空 List
PropertyDefinitionList : PropertyDefinition
  1. 返回 « PropertyDefinition »。
PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. head 为派生的 PropertyDefinitionListPropertyDefinitionNodes
  2. 返回 head 和 « PropertyDefinition » 的列表连接

13.2.5.4 Static Semantics: PropertyNameList

The syntax-directed operation PropertyNameList takes no arguments and returns a List of Strings. It is defined piecewise over the following productions:

PropertyDefinitionList : PropertyDefinition
  1. propertyNamePropertyDefinitionPropName
  2. 如果 propertyNameempty,则返回一个新的空 List
  3. 返回 « propertyName »。
PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. listPropertyDefinitionListPropertyNameList
  2. propertyNamePropertyDefinitionPropName
  3. 如果 propertyNameempty,则返回 list
  4. 返回 list 和 « propertyName » 的列表连接

13.2.5.5 Runtime Semantics: Evaluation

ObjectLiteral : { }
  1. 返回 OrdinaryObjectCreate(%Object.prototype%)。
ObjectLiteral : { PropertyDefinitionList } { PropertyDefinitionList , }
  1. objOrdinaryObjectCreate(%Object.prototype%)。
  2. 执行 ? 以 obj 为实参执行 PropertyDefinitionListPropertyDefinitionEvaluation
  3. 返回 obj
LiteralPropertyName : IdentifierName
  1. 返回 IdentifierNameStringValue
LiteralPropertyName : StringLiteral
  1. 返回 StringLiteralSV
LiteralPropertyName : NumericLiteral
  1. numberNumericLiteralNumericValue
  2. 返回 ! ToString(number)。
ComputedPropertyName : [ AssignmentExpression ]
  1. exprValue 为 ? AssignmentExpressionEvaluation
  2. propertyName 为 ? GetValue(exprValue)。
  3. 返回 ? ToPropertyKey(propertyName)。

13.2.5.6 Runtime Semantics: PropertyDefinitionEvaluation

The syntax-directed operation PropertyDefinitionEvaluation takes argument obj (an Object) and returns either a normal completion containing unused or an abrupt completion. It is defined piecewise over the following productions:

PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. 执行 ? 以 obj 为实参执行 PropertyDefinitionListPropertyDefinitionEvaluation
  2. 执行 ? 以 obj 为实参执行 PropertyDefinitionPropertyDefinitionEvaluation
  3. 返回 unused
PropertyDefinition : ... AssignmentExpression
  1. exprValue 为 ? AssignmentExpressionEvaluation
  2. fromValue 为 ? GetValue(exprValue)。
  3. excludedNames 为新的空 List
  4. 执行 ? CopyDataProperties(obj, fromValue, excludedNames)。
  5. 返回 unused
PropertyDefinition : IdentifierReference
  1. propertyNameIdentifierReferenceStringValue
  2. exprValue 为 ? IdentifierReferenceEvaluation
  3. propertyValue 为 ? GetValue(exprValue)。
  4. 断言:obj 是一个普通的、可扩展的对象,且没有不可配置属性。
  5. 执行 ! CreateDataPropertyOrThrow(obj, propertyName, propertyValue)。
  6. 返回 unused
PropertyDefinition : PropertyName : AssignmentExpression
  1. propertyKey 为 ? PropertyNameEvaluation
  2. 如果此 PropertyDefinition 包含在正为 ParseJSON 求值的 Script 内(参见 ParseJSON 的步骤 6),则
    1. isProtoSetterfalse
  3. 否则,如果 propertyKey"__proto__"PropertyNameIsComputedPropertyKeyfalse,则
    1. isProtoSettertrue
  4. 否则,
    1. isProtoSetterfalse
  5. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 trueisProtoSetterfalse,则
    1. propertyValue 为 ? 以 propertyKey 为实参执行 AssignmentExpressionNamedEvaluation
  6. 否则,
    1. exprValueRef 为 ? AssignmentExpressionEvaluation
    2. propertyValue 为 ? GetValue(exprValueRef)。
  7. 如果 isProtoSettertrue,则
    1. 如果 propertyValue 是 Object 或 propertyValuenull,则
      1. 执行 ! obj.[[SetPrototypeOf]](propertyValue)
    2. 返回 unused
  8. 断言:obj 是一个普通的、可扩展的对象,且没有不可配置属性。
  9. 执行 ! CreateDataPropertyOrThrow(obj, propertyKey, propertyValue)。
  10. 返回 unused
PropertyDefinition : MethodDefinition
  1. 执行 ? 以 objtrue 为实参执行 MethodDefinitionMethodDefinitionEvaluation
  2. 返回 unused

13.2.6 函数定义表达式

关于 PrimaryExpression : FunctionExpression ,参见 15.2

关于 PrimaryExpression : GeneratorExpression ,参见 15.5

关于 PrimaryExpression : ClassExpression ,参见 15.7

关于 PrimaryExpression : AsyncFunctionExpression ,参见 15.8

关于 PrimaryExpression : AsyncGeneratorExpression ,参见 15.6

13.2.7 正则表达式字面量

语法

参见 12.9.5

13.2.7.1 Static Semantics: 早期错误

PrimaryExpression : RegularExpressionLiteral

13.2.7.2 Static Semantics: IsValidRegularExpressionLiteral ( literal )

The abstract operation IsValidRegularExpressionLiteral takes argument literal (a RegularExpressionLiteral Parse Node) and returns a Boolean. 它确定其实参是否是有效的正则表达式字面量。 It performs the following steps when called:

  1. flagsliteralFlagText
  2. 如果 flags 包含dgimsuvy 之外的任何码点,则返回 false
  3. 如果 flags 包含任何出现次数超过一次的码点,则返回 false
  4. 如果 flags 包含 u,则令 utrue;否则令 ufalse
  5. 如果 flags 包含 v,则令 vtrue;否则令 vfalse
  6. patternTextliteralBodyText
  7. 如果 ufalsevfalse,则
    1. stringValueCodePointsToString(patternText)。
    2. patternText 设置为将 stringValue 的每个 16 位元素解释为 Unicode BMP 码点所得的码点序列。不会对这些元素应用 UTF-16 解码。
  8. parseResultParsePattern(patternText, u, v)。
  9. 如果 parseResultParse Node,则返回 true
  10. 返回 false

13.2.7.3 Runtime Semantics: Evaluation

PrimaryExpression : RegularExpressionLiteral
  1. patternCodePointsToString(RegularExpressionLiteralBodyText)。
  2. flagsCodePointsToString(RegularExpressionLiteralFlagText)。
  3. 返回 ! RegExpCreate(pattern, flags)。

13.2.8 模板字面量

语法

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.8.1 Static Semantics: 早期错误

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.8.2 Static Semantics: TemplateStrings

The syntax-directed operation TemplateStrings takes argument raw (a Boolean) and returns a List of either Strings or undefined. It is defined piecewise over the following productions:

TemplateLiteral : NoSubstitutionTemplate
  1. 返回 « TemplateString(NoSubstitutionTemplate, raw) »。
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. head 为 « TemplateString(TemplateHead, raw) »。
  2. tail 为以 raw 为实参的 TemplateSpansTemplateStrings
  3. 返回 headtail列表连接
TemplateSpans : TemplateTail
  1. 返回 « TemplateString(TemplateTail, raw) »。
TemplateSpans : TemplateMiddleList TemplateTail
  1. middle 为以 raw 为实参的 TemplateMiddleListTemplateStrings
  2. tail 为 « TemplateString(TemplateTail, raw) »。
  3. 返回 middletail列表连接
TemplateMiddleList : TemplateMiddle Expression
  1. 返回 « TemplateString(TemplateMiddle, raw) »。
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. front 为以 raw 为实参的 TemplateMiddleListTemplateStrings
  2. last 为 « TemplateString(TemplateMiddle, raw) »。
  3. 返回 frontlast列表连接

13.2.8.3 Static Semantics: TemplateString ( templateToken, raw )

The abstract operation TemplateString takes arguments templateToken (a NoSubstitutionTemplate Parse Node, a TemplateHead Parse Node, a TemplateMiddle Parse Node, or a TemplateTail Parse Node) and raw (a Boolean) and returns a String or undefined. It performs the following steps when called:

  1. 如果 rawtrue,则
    1. stringtemplateTokenTRV
  2. 否则,
    1. stringtemplateTokenTV
  3. 返回 string
Note

如果 rawfalsetemplateToken 包含 NotEscapeSequence,则此操作返回 undefined。在所有其他情况下,它返回 String。

13.2.8.4 GetTemplateObject ( templateLiteral )

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

  1. realm当前 Realm Record
  2. templateRegistryrealm.[[TemplateMap]]
  3. templateRegistry 的每个元素 element,执行:
    1. 如果 element.[[Site]]templateLiteral 是同一个 Parse Node,则
      1. 返回 element.[[Array]]
  4. rawStrings 为以 true 为实参的 templateLiteralTemplateStrings
  5. 断言:rawStrings 是 Strings 的 List
  6. cookedStrings 为以 false 为实参的 templateLiteralTemplateStrings
  7. countList cookedStrings 中元素的数量。
  8. 断言:count ≤ 232 - 1。
  9. template 为 ! ArrayCreate(count)。
  10. rawObj 为 ! ArrayCreate(count)。
  11. index 为 0。
  12. 重复,当 index < count 时,
    1. propertyKey 为 ! ToString(𝔽(index))。
    2. cookedValuecookedStrings[index]。
    3. 执行 ! DefinePropertyOrThrow(template, propertyKey, PropertyDescriptor { [[Value]]: cookedValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false })。
    4. rawValue 为 String 值 rawStrings[index]。
    5. 执行 ! DefinePropertyOrThrow(rawObj, propertyKey, PropertyDescriptor { [[Value]]: rawValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false })。
    6. index 设置为 index + 1。
  13. 执行 ! SetIntegrityLevel(rawObj, frozen)。
  14. 执行 ! DefinePropertyOrThrow(template, "raw", PropertyDescriptor { [[Value]]: rawObj, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。
  15. 执行 ! SetIntegrityLevel(template, frozen)。
  16. Record { [[Site]]: templateLiteral, [[Array]]: template } 追加到 realm.[[TemplateMap]]
  17. 返回 template
Note 1

创建模板对象不会导致 abrupt completion。

Note 2

realm 的程序代码中的每个 TemplateLiteral 都与一个唯一的模板对象关联,该模板对象用于带标签 Template 的求值(13.2.8.6)。模板对象被冻结,并且每次求值特定带标签 Template 时都使用同一个模板对象。模板对象是在首次求值 TemplateLiteral 时惰性创建,还是在首次求值之前急切创建,是实现选择,对 ECMAScript 代码不可观察。

Note 3

本规范的未来版本可能会定义模板对象的附加不可枚举属性。

13.2.8.5 Runtime Semantics: SubstitutionEvaluation

The syntax-directed operation SubstitutionEvaluation takes no arguments and returns either a normal completion containing a List of ECMAScript language values or an abrupt completion. It is defined piecewise over the following productions:

TemplateSpans : TemplateTail
  1. 返回一个新的空 List
TemplateSpans : TemplateMiddleList TemplateTail
  1. 返回 ? TemplateMiddleListSubstitutionEvaluation
TemplateMiddleList : TemplateMiddle Expression
  1. subRef 为 ? ExpressionEvaluation
  2. sub 为 ? GetValue(subRef)。
  3. 返回 « sub »。
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. preceding 为 ? TemplateMiddleListSubstitutionEvaluation
  2. nextRef 为 ? ExpressionEvaluation
  3. next 为 ? GetValue(nextRef)。
  4. 返回 preceding 和 « next » 的列表连接

13.2.8.6 Runtime Semantics: Evaluation

TemplateLiteral : NoSubstitutionTemplate
  1. 返回 12.9.6 中定义的 NoSubstitutionTemplateTV
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. head12.9.6 中定义的 TemplateHeadTV
  2. subRef 为 ? ExpressionEvaluation
  3. sub 为 ? GetValue(subRef)。
  4. middle 为 ? ToString(sub)。
  5. tail 为 ? TemplateSpansEvaluation
  6. 返回 headmiddletail字符串连接
Note 1

应用于 Expression 值的字符串转换语义类似于 String.prototype.concat,而不是 + 运算符。

TemplateSpans : TemplateTail
  1. 返回 12.9.6 中定义的 TemplateTailTV
TemplateSpans : TemplateMiddleList TemplateTail
  1. head 为 ? TemplateMiddleListEvaluation
  2. tail12.9.6 中定义的 TemplateTailTV
  3. 返回 headtail字符串连接
TemplateMiddleList : TemplateMiddle Expression
  1. head12.9.6 中定义的 TemplateMiddleTV
  2. subRef 为 ? ExpressionEvaluation
  3. sub 为 ? GetValue(subRef)。
  4. middle 为 ? ToString(sub)。
  5. 返回 headmiddle字符串连接
Note 2

应用于 Expression 值的字符串转换语义类似于 String.prototype.concat,而不是 + 运算符。

TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. rest 为 ? TemplateMiddleListEvaluation
  2. middle12.9.6 中定义的 TemplateMiddleTV
  3. subRef 为 ? ExpressionEvaluation
  4. sub 为 ? GetValue(subRef)。
  5. last 为 ? ToString(sub)。
  6. 返回 restmiddlelast字符串连接
Note 3

应用于 Expression 值的字符串转换语义类似于 String.prototype.concat,而不是 + 运算符。

13.2.9 分组运算符

13.2.9.1 Static Semantics: 早期错误

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList

13.2.9.2 Runtime Semantics: Evaluation

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. expr 为由 CoverParenthesizedExpressionAndArrowParameterList 覆盖的 ParenthesizedExpression
  2. 返回 ? exprEvaluation
ParenthesizedExpression : ( Expression )
  1. 返回 ? ExpressionEvaluation。这可能是 Reference 类型。
Note

此算法不会对 ExpressionEvaluation 应用 GetValue。其主要动机是让 deletetypeof 等运算符可以应用于带括号表达式。

13.3 左手边表达式

语法

MemberExpression[Yield, Await] : PrimaryExpression[?Yield, ?Await] MemberExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] MemberExpression[?Yield, ?Await] . IdentifierName MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] SuperProperty[?Yield, ?Await] MetaProperty new MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] MemberExpression[?Yield, ?Await] . PrivateIdentifier SuperProperty[Yield, Await] : super [ Expression[+In, ?Yield, ?Await] ] super . IdentifierName MetaProperty : NewTarget ImportMeta NewTarget : new . target ImportMeta : import . meta NewExpression[Yield, Await] : MemberExpression[?Yield, ?Await] new NewExpression[?Yield, ?Await] CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] SuperCall[?Yield, ?Await] ImportCall[?Yield, ?Await] CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await] CallExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] CallExpression[?Yield, ?Await] . IdentifierName CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] CallExpression[?Yield, ?Await] . PrivateIdentifier SuperCall[Yield, Await] : super Arguments[?Yield, ?Await] ImportCall[Yield, Await] : import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) Arguments[Yield, Await] : ( ) ( ArgumentList[?Yield, ?Await] ) ( ArgumentList[?Yield, ?Await] , ) ArgumentList[Yield, Await] : AssignmentExpression[+In, ?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , ... AssignmentExpression[+In, ?Yield, ?Await] OptionalExpression[Yield, Await] : MemberExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalChain[Yield, Await] : ?. Arguments[?Yield, ?Await] ?. [ Expression[+In, ?Yield, ?Await] ] ?. IdentifierName ?. TemplateLiteral[?Yield, ?Await, +Tagged] ?. PrivateIdentifier OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await] OptionalChain[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] OptionalChain[?Yield, ?Await] . IdentifierName OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] OptionalChain[?Yield, ?Await] . PrivateIdentifier LeftHandSideExpression[Yield, Await] : NewExpression[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalExpression[?Yield, ?Await]

补充语法

当处理产生式的实例
CallExpression : CoverCallExpressionAndAsyncArrowHead
时,使用以下语法细化 CoverCallExpressionAndAsyncArrowHead 的解释:

CallMemberExpression[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

13.3.1 静态语义

13.3.1.1 Static Semantics: 早期错误

OptionalChain : ?. TemplateLiteral OptionalChain TemplateLiteral
  • 如果此产生式匹配到任何源文本,则为语法错误。
Note

此产生式存在是为了防止自动分号插入规则(12.10)应用于以下代码:

a?.b
`c`

从而避免其被解释为两个有效语句。其目的是保持与没有可选链的类似代码一致:

a.b
`c`

这是一个有效语句,且不会应用自动分号插入。

ImportMeta : import . meta

13.3.2 属性访问器

Note

属性通过名称访问,使用点号记法:

或方括号记法:

点号记法由以下句法转换解释:

在行为上等同于

MemberExpression [ <identifier-name-string> ]

并且类似地

在行为上等同于

CallExpression [ <identifier-name-string> ]

其中 <identifier-name-string> 是 IdentifierNameStringValue

13.3.2.1 Runtime Semantics: Evaluation

MemberExpression : MemberExpression [ Expression ]
  1. baseRef 为 ? MemberExpressionEvaluation
  2. baseValue 为 ? GetValue(baseRef)。
  3. strictIsStrict(this MemberExpression)。
  4. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
MemberExpression : MemberExpression . IdentifierName
  1. baseRef 为 ? MemberExpressionEvaluation
  2. baseValue 为 ? GetValue(baseRef)。
  3. strictIsStrict(this MemberExpression)。
  4. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
MemberExpression : MemberExpression . PrivateIdentifier
  1. baseRef 为 ? MemberExpressionEvaluation
  2. baseValue 为 ? GetValue(baseRef)。
  3. fieldNameStringPrivateIdentifierStringValue
  4. 返回 MakePrivateReference(baseValue, fieldNameString)。
CallExpression : CallExpression [ Expression ]
  1. baseRef 为 ? CallExpressionEvaluation
  2. baseValue 为 ? GetValue(baseRef)。
  3. strictIsStrict(this CallExpression)。
  4. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
CallExpression : CallExpression . IdentifierName
  1. baseRef 为 ? CallExpressionEvaluation
  2. baseValue 为 ? GetValue(baseRef)。
  3. strictIsStrict(this CallExpression)。
  4. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
CallExpression : CallExpression . PrivateIdentifier
  1. baseRef 为 ? CallExpressionEvaluation
  2. baseValue 为 ? GetValue(baseRef)。
  3. fieldNameStringPrivateIdentifierStringValue
  4. 返回 MakePrivateReference(baseValue, fieldNameString)。

13.3.3 EvaluatePropertyAccessWithExpressionKey ( baseValue, expr, strict )

The abstract operation EvaluatePropertyAccessWithExpressionKey takes arguments baseValue (an ECMAScript language value), expr (an Expression Parse Node), and strict (a Boolean) and returns either a normal completion containing a Reference Record or an abrupt completion. It performs the following steps when called:

  1. propertyNameRef 为 ? exprEvaluation
  2. propertyNameValue 为 ? GetValue(propertyNameRef)。
  3. 注:在大多数情况下,ToPropertyKey 会在此步骤之后立即对 propertyNameValue 执行。不过,在 a[b] = c 的情况下,它要到 c 求值之后才会执行。
  4. 返回 Reference Record { [[Base]]: baseValue, [[ReferencedName]]: propertyNameValue, [[Strict]]: strict, [[ThisValue]]: empty }。

13.3.4 EvaluatePropertyAccessWithIdentifierKey ( baseValue, identifierName, strict )

The abstract operation EvaluatePropertyAccessWithIdentifierKey takes arguments baseValue (an ECMAScript language value), identifierName (an IdentifierName Parse Node), and strict (a Boolean) and returns a Reference Record. It performs the following steps when called:

  1. propertyNameStringidentifierNameStringValue
  2. 返回 Reference Record { [[Base]]: baseValue, [[ReferencedName]]: propertyNameString, [[Strict]]: strict, [[ThisValue]]: empty }。

13.3.5 new 运算符

13.3.5.1 Runtime Semantics: Evaluation

NewExpression : new NewExpression
  1. 返回 ? EvaluateNew(NewExpression, empty)。
MemberExpression : new MemberExpression Arguments
  1. 返回 ? EvaluateNew(MemberExpression, Arguments)。

13.3.5.1.1 EvaluateNew ( constructExpr, argumentsNode )

The abstract operation EvaluateNew takes arguments constructExpr (a NewExpression Parse Node or a MemberExpression Parse Node) and argumentsNode (empty or an Arguments Parse Node) and returns either a normal completion containing an Object or an abrupt completion. It performs the following steps when called:

  1. ref 为 ? constructExprEvaluation
  2. ctor 为 ? GetValue(ref)。
  3. 如果 argumentsNodeempty,则
    1. argList 为一个新的空 List
  4. 否则,
    1. argList 为 ? argumentsNodeArgumentListEvaluation
  5. 如果 IsConstructor(ctor) 是 false,则抛出 TypeError 异常。
  6. 返回 ? Construct(ctor, argList)。

13.3.6 函数调用

13.3.6.1 Runtime Semantics: Evaluation

CallExpression : CoverCallExpressionAndAsyncArrowHead
  1. expr 为由 CoverCallExpressionAndAsyncArrowHead 覆盖的 CallMemberExpression
  2. memberExprexprMemberExpression
  3. argsexprArguments
  4. ref 为 ? memberExprEvaluation
  5. func 为 ? GetValue(ref)。
  6. 如果 refReference RecordIsPropertyReference(ref) 是 false,且 ref.[[ReferencedName]]"eval",则
    1. 如果 SameValue(func, %eval%) 是 true,则
      1. argList 为 ? argsArgumentListEvaluation
      2. 如果 argList 没有元素,则返回 undefined
      3. evalArgargList 的第一个元素。
      4. 如果 IsStrict(this CallExpression) 是 true,则令 strictCallertrue;否则令 strictCallerfalse
      5. 返回 ? PerformEval(evalArg, strictCaller, true)。
  7. thisCall 为此 CallExpression
  8. tailCallIsInTailPosition(thisCall)。
  9. 返回 ? EvaluateCall(func, ref, args, tailCall)。

执行步骤 6.a.vCallExpression 求值是 direct eval

CallExpression : CallExpression Arguments
  1. ref 为 ? CallExpressionEvaluation
  2. func 为 ? GetValue(ref)。
  3. thisCall 为此 CallExpression
  4. tailCallIsInTailPosition(thisCall)。
  5. 返回 ? EvaluateCall(func, ref, Arguments, tailCall)。

13.3.6.2 EvaluateCall ( func, thisValueRef, argumentListNode, tailPosition )

The abstract operation EvaluateCall takes arguments func (an ECMAScript language value), thisValueRef (an ECMAScript language value or a Reference Record), argumentListNode (a Parse Node), and tailPosition (a Boolean) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. 如果 thisValueRefReference Record,则
    1. 如果 IsPropertyReference(thisValueRef) 是 true,则
      1. thisValueGetThisValue(thisValueRef)。
    2. 否则,
      1. refEnvthisValueRef.[[Base]]
      2. 断言:refEnvEnvironment Record
      3. thisValuerefEnv.WithBaseObject()。
  2. 否则,
    1. thisValueundefined
  3. argList 为 ? argumentListNodeArgumentListEvaluation
  4. 如果 func 不是 Object,则抛出 TypeError 异常。
  5. 如果 IsCallable(func) 是 false,则抛出 TypeError 异常。
  6. 如果 tailPositiontrue,则执行 PrepareForTailCall()。
  7. 返回 ? Call(func, thisValue, argList)。

13.3.7 super 关键字

13.3.7.1 Runtime Semantics: Evaluation

SuperProperty : super [ Expression ]
  1. envRecordGetThisEnvironment()。
  2. actualThis 为 ? envRecord.GetThisBinding()。
  3. propertyNameRef 为 ? ExpressionEvaluation
  4. propertyNameValue 为 ? GetValue(propertyNameRef)。
  5. strictIsStrict(this SuperProperty)。
  6. 注:在大多数情况下,ToPropertyKey 会在此步骤之后立即对 propertyNameValue 执行。不过,在 super[b] = c 的情况下,它要到 c 求值之后才会执行。
  7. 返回 MakeSuperPropertyReference(actualThis, propertyNameValue, strict)。
SuperProperty : super . IdentifierName
  1. envRecordGetThisEnvironment()。
  2. actualThis 为 ? envRecord.GetThisBinding()。
  3. propertyKeyIdentifierNameStringValue
  4. strictIsStrict(this SuperProperty)。
  5. 返回 MakeSuperPropertyReference(actualThis, propertyKey, strict)。
SuperCall : super Arguments
  1. newTargetGetNewTarget()。
  2. 断言:newTarget 是 constructor。
  3. superCtorGetSuperConstructor()。
  4. argList 为 ? ArgumentsArgumentListEvaluation
  5. 如果 IsConstructor(superCtor) 是 false,则抛出 TypeError 异常。
  6. result 为 ? Construct(superCtor, argList, newTarget)。
  7. thisERGetThisEnvironment()。
  8. 断言:thisERFunction Environment Record
  9. 执行 ? BindThisValue(thisER, result)。
  10. funcObjthisER.[[FunctionObject]]
  11. 断言:funcObj 是 ECMAScript 函数对象
  12. 执行 ? InitializeInstanceElements(result, funcObj)。
  13. 返回 result

13.3.7.2 GetSuperConstructor ( )

The abstract operation GetSuperConstructor takes no arguments and returns an Object or null. It performs the following steps when called:

  1. envRecordGetThisEnvironment()。
  2. 断言:envRecordFunction Environment Record
  3. activeFuncenvRecord.[[FunctionObject]]
  4. 断言:activeFunc 是 ECMAScript 函数对象
  5. superCtor 为 ! activeFunc.[[GetPrototypeOf]]()。
  6. 返回 superCtor

13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict )

The abstract operation MakeSuperPropertyReference takes arguments actualThis (an ECMAScript language value), propertyKey (an ECMAScript language value), and strict (a Boolean) and returns a Super Reference Record. It performs the following steps when called:

  1. envRecordGetThisEnvironment()。
  2. 断言:envRecord.HasSuperBinding() 是 true
  3. 断言:envRecordFunction Environment Record
  4. baseValueGetSuperBase(envRecord)。
  5. 返回 Reference Record { [[Base]]: baseValue, [[ReferencedName]]: propertyKey, [[Strict]]: strict, [[ThisValue]]: actualThis }。

13.3.8 实参列表

Note

求值实参列表会产生一个值的 List

13.3.8.1 Runtime Semantics: ArgumentListEvaluation

The syntax-directed operation ArgumentListEvaluation takes no arguments and returns either a normal completion containing a List of ECMAScript language values or an abrupt completion. It is defined piecewise over the following productions:

Arguments : ( )
  1. 返回一个新的空 List
ArgumentList : AssignmentExpression
  1. ref 为 ? AssignmentExpressionEvaluation
  2. arg 为 ? GetValue(ref)。
  3. 返回 « arg »。
ArgumentList : ... AssignmentExpression
  1. list 为一个新的空 List
  2. spreadRef 为 ? AssignmentExpressionEvaluation
  3. spreadObj 为 ? GetValue(spreadRef)。
  4. iteratorRecord 为 ? GetIterator(spreadObj, sync)。
  5. 重复:
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,则返回 list
    3. next 追加到 list
ArgumentList : ArgumentList , AssignmentExpression
  1. precedingArgs 为 ? ArgumentListArgumentListEvaluation
  2. ref 为 ? AssignmentExpressionEvaluation
  3. arg 为 ? GetValue(ref)。
  4. 返回 precedingArgs 和 « arg » 的列表连接
ArgumentList : ArgumentList , ... AssignmentExpression
  1. precedingArgs 为 ? ArgumentListArgumentListEvaluation
  2. spreadRef 为 ? AssignmentExpressionEvaluation
  3. iteratorRecord 为 ? GetIterator(? GetValue(spreadRef), sync)。
  4. 重复:
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,则返回 precedingArgs
    3. next 追加到 precedingArgs
TemplateLiteral : NoSubstitutionTemplate
  1. templateLiteral 为此 TemplateLiteral
  2. siteObjGetTemplateObject(templateLiteral)。
  3. 返回 « siteObj »。
TemplateLiteral : SubstitutionTemplate
  1. templateLiteral 为此 TemplateLiteral
  2. siteObjGetTemplateObject(templateLiteral)。
  3. remaining 为 ? SubstitutionTemplateArgumentListEvaluation
  4. 返回 « siteObj » 和 remaining列表连接
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. firstSubRef 为 ? ExpressionEvaluation
  2. firstSub 为 ? GetValue(firstSubRef)。
  3. restSub 为 ? TemplateSpansSubstitutionEvaluation
  4. 断言:restSub 是一个可能为空的 List
  5. 返回 « firstSub » 和 restSub列表连接

13.3.9 可选链

Note
可选链是一个由一个或多个属性访问和函数调用组成的链,其中第一个以 token ?. 开头。

13.3.9.1 Runtime Semantics: Evaluation

OptionalExpression : MemberExpression OptionalChain
  1. baseRef 为 ? MemberExpressionEvaluation
  2. baseValue 为 ? GetValue(baseRef)。
  3. 如果 baseValueundefinednull,则
    1. 返回 undefined
  4. 返回 ? 以 baseValuebaseRef 为实参执行 OptionalChainChainEvaluation
OptionalExpression : CallExpression OptionalChain
  1. baseRef 为 ? CallExpressionEvaluation
  2. baseValue 为 ? GetValue(baseRef)。
  3. 如果 baseValueundefinednull,则
    1. 返回 undefined
  4. 返回 ? 以 baseValuebaseRef 为实参执行 OptionalChainChainEvaluation
OptionalExpression : OptionalExpression OptionalChain
  1. baseRef 为 ? OptionalExpressionEvaluation
  2. baseValue 为 ? GetValue(baseRef)。
  3. 如果 baseValueundefinednull,则
    1. 返回 undefined
  4. 返回 ? 以 baseValuebaseRef 为实参执行 OptionalChainChainEvaluation

13.3.9.2 Runtime Semantics: ChainEvaluation

The syntax-directed operation ChainEvaluation takes arguments baseValue (an ECMAScript language value) and baseRef (an ECMAScript language value or a Reference Record) and returns either a normal completion containing either an ECMAScript language value or a Reference Record, or an abrupt completion. It is defined piecewise over the following productions:

OptionalChain : ?. Arguments
  1. thisChain 为此 OptionalChain
  2. tailCallIsInTailPosition(thisChain)。
  3. 返回 ? EvaluateCall(baseValue, baseRef, Arguments, tailCall)。
OptionalChain : ?. [ Expression ]
  1. strictIsStrict(this OptionalChain)。
  2. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
OptionalChain : ?. IdentifierName
  1. strictIsStrict(this OptionalChain)。
  2. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
OptionalChain : ?. PrivateIdentifier
  1. fieldNameStringPrivateIdentifierStringValue
  2. 返回 MakePrivateReference(baseValue, fieldNameString)。
OptionalChain : OptionalChain Arguments
  1. optionalChainOptionalChain
  2. newRef 为 ? 以 baseValuebaseRef 为实参执行 optionalChainChainEvaluation
  3. newValue 为 ? GetValue(newRef)。
  4. thisChain 为此 OptionalChain
  5. tailCallIsInTailPosition(thisChain)。
  6. 返回 ? EvaluateCall(newValue, newRef, Arguments, tailCall)。
OptionalChain : OptionalChain [ Expression ]
  1. optionalChainOptionalChain
  2. newRef 为 ? 以 baseValuebaseRef 为实参执行 optionalChainChainEvaluation
  3. newValue 为 ? GetValue(newRef)。
  4. strictIsStrict(this OptionalChain)。
  5. 返回 ? EvaluatePropertyAccessWithExpressionKey(newValue, Expression, strict)。
OptionalChain : OptionalChain . IdentifierName
  1. optionalChainOptionalChain
  2. newRef 为 ? 以 baseValuebaseRef 为实参执行 optionalChainChainEvaluation
  3. newValue 为 ? GetValue(newRef)。
  4. strictIsStrict(this OptionalChain)。
  5. 返回 EvaluatePropertyAccessWithIdentifierKey(newValue, IdentifierName, strict)。
OptionalChain : OptionalChain . PrivateIdentifier
  1. optionalChainOptionalChain
  2. newRef 为 ? 以 baseValuebaseRef 为实参执行 optionalChainChainEvaluation
  3. newValue 为 ? GetValue(newRef)。
  4. fieldNameStringPrivateIdentifierStringValue
  5. 返回 MakePrivateReference(newValue, fieldNameString)。

13.3.10 Import 调用

13.3.10.1 Runtime Semantics: Evaluation

ImportCall : import ( AssignmentExpression ,opt )
  1. 返回 ? EvaluateImportCall(AssignmentExpression)。
ImportCall : import ( AssignmentExpression , AssignmentExpression ,opt )
  1. 返回 ? EvaluateImportCall(第一个 AssignmentExpression, 第二个 AssignmentExpression)。

13.3.10.2 EvaluateImportCall ( specifierExpr [ , optionsExpr ] )

The abstract operation EvaluateImportCall takes argument specifierExpr (a Parse Node) and optional argument optionsExpr (a Parse Node) and returns either a normal completion containing a Promise or an abrupt completion. It performs the following steps when called:

  1. referrerGetActiveScriptOrModule()。
  2. 如果 referrernull,则将 referrer 设置为当前 Realm Record
  3. specifierRef 为 ? specifierExprEvaluation
  4. specifier 为 ? GetValue(specifierRef)。
  5. 如果 optionsExpr 存在,则
    1. optionsRef 为 ? optionsExprEvaluation
    2. options 为 ? GetValue(optionsRef)。
  6. 否则,
    1. optionsundefined
  7. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  8. specifierStringCompletion(ToString(specifier))。
  9. IfAbruptRejectPromise(specifierString, promiseCapability)。
  10. attrs 为新的空 List
  11. 如果 options 不是 undefined,则
    1. 如果 options 不是 Object,则
      1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 一个新创建的 TypeError 对象 »)。
      2. 返回 promiseCapability.[[Promise]]
    2. attrsObjCompletion(Get(options, "with")))。
    3. IfAbruptRejectPromise(attrsObj, promiseCapability)。
    4. 如果 attrsObj 不是 undefined,则
      1. 如果 attrsObj 不是 Object,则
        1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 一个新创建的 TypeError 对象 »)。
        2. 返回 promiseCapability.[[Promise]]
      2. entriesCompletion(EnumerableOwnProperties(attrsObj, key+value))。
      3. IfAbruptRejectPromise(entries, promiseCapability)。
      4. entries 的每个元素 entry,执行:
        1. key 为 ! Get(entry, "0")。
        2. value 为 ! Get(entry, "1")。
        3. 如果 key 是 String,则
          1. 如果 value 不是 String,则
            1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 一个新创建的 TypeError 对象 »)。
            2. 返回 promiseCapability.[[Promise]]
          2. ImportAttribute Record { [[Key]]: key, [[Value]]: value } 追加到 attrs
    5. 如果 AllImportAttributesSupported(attrs) 是 false,则
      1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 一个新创建的 TypeError 对象 »)。
      2. 返回 promiseCapability.[[Promise]]
    6. 按照 attrs[[Key]] 字段的词典序对 attrs 进行排序,并将每个这种字段的值视为 UTF-16 代码单元值序列。注:此排序唯一可观察之处在于,宿主被禁止基于属性枚举顺序改变行为。
  12. moduleRequest 为一个新的 ModuleRequest Record { [[Specifier]]: specifierString, [[Attributes]]: attrs }。
  13. 执行 HostLoadImportedModule(referrer, moduleRequest, empty, promiseCapability)。
  14. 返回 promiseCapability.[[Promise]]

13.3.10.3 ContinueDynamicImport ( promiseCapability, moduleCompletion )

The abstract operation ContinueDynamicImport takes arguments promiseCapability (a PromiseCapability Record) and moduleCompletion (either a normal completion containing a Module Record or a throw completion) and returns unused. 它完成最初由 import() 调用启动的动态 import 过程,并根据情况 resolve 或 reject 该调用返回的 promise。 It performs the following steps when called:

  1. 如果 moduleCompletion 是 abrupt completion,则
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « moduleCompletion.[[Value]] »)。
    2. 返回 unused
  2. modulemoduleCompletion.[[Value]]
  3. loadPromisemodule.LoadRequestedModules()。
  4. rejectedClosure 为一个具有形参 (reason) 的新 Abstract Closure,它捕获 promiseCapability,并在被调用时执行以下步骤:
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « reason »)。
    2. 返回 NormalCompletion(undefined)。
  5. onRejectedCreateBuiltinFunction(rejectedClosure, 1, "", « »)。
  6. linkAndEvaluateClosure 为一个不带形参的新 Abstract Closure,它捕获 modulepromiseCapabilityonRejected,并在被调用时执行以下步骤:
    1. linkCompletion(module.Link())。
    2. 如果 link 是 abrupt completion,则
      1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « link.[[Value]] »)。
      2. 返回 NormalCompletion(undefined)。
    3. evaluatePromisemodule.Evaluate()。
    4. fulfilledClosure 为一个不带形参的新 Abstract Closure,它捕获 modulepromiseCapability,并在被调用时执行以下步骤:
      1. namespaceGetModuleNamespace(module)。
      2. 执行 ! Call(promiseCapability.[[Resolve]], undefined, « namespace »)。
      3. 返回 NormalCompletion(undefined)。
    5. onFulfilledCreateBuiltinFunction(fulfilledClosure, 0, "", « »)。
    6. 执行 PerformPromiseThen(evaluatePromise, onFulfilled, onRejected)。
    7. 返回 unused
  7. linkAndEvaluateCreateBuiltinFunction(linkAndEvaluateClosure, 0, "", « »)。
  8. 执行 PerformPromiseThen(loadPromise, linkAndEvaluate, onRejected)。
  9. 返回 unused

13.3.11 带标签模板

Note

带标签模板是一种函数调用,其中该调用的实参派生自 TemplateLiteral13.2.8)。实际实参包括一个模板对象(13.2.8.4)以及通过求值嵌入在 TemplateLiteral 内部的表达式所产生的值。

13.3.11.1 Runtime Semantics: Evaluation

MemberExpression : MemberExpression TemplateLiteral
  1. tagRef 为 ? MemberExpressionEvaluation
  2. tagFunc 为 ? GetValue(tagRef)。
  3. thisCall 为此 MemberExpression
  4. tailCallIsInTailPosition(thisCall)。
  5. 返回 ? EvaluateCall(tagFunc, tagRef, TemplateLiteral, tailCall)。
CallExpression : CallExpression TemplateLiteral
  1. tagRef 为 ? CallExpressionEvaluation
  2. tagFunc 为 ? GetValue(tagRef)。
  3. thisCall 为此 CallExpression
  4. tailCallIsInTailPosition(thisCall)。
  5. 返回 ? EvaluateCall(tagFunc, tagRef, TemplateLiteral, tailCall)。

13.3.12 元属性

13.3.12.1 Runtime Semantics: Evaluation

NewTarget : new . target
  1. 返回 GetNewTarget()。
ImportMeta : import . meta
  1. moduleGetActiveScriptOrModule()。
  2. 断言:moduleSource Text Module Record
  3. importMetamodule.[[ImportMeta]]
  4. 如果 importMetaempty,则
    1. importMeta 设置为 OrdinaryObjectCreate(null)。
    2. importMetaValuesHostGetImportMetaProperties(module)。
    3. importMetaValues 的每个 Record { [[Key]], [[Value]] } entry,执行:
      1. 执行 ! CreateDataPropertyOrThrow(importMeta, entry.[[Key]], entry.[[Value]])。
    4. 执行 HostFinalizeImportMeta(importMeta, module)。
    5. module.[[ImportMeta]] 设置为 importMeta
    6. 返回 importMeta
  5. 断言:importMeta 是 Object。
  6. 返回 importMeta

13.3.12.1.1 HostGetImportMetaProperties ( moduleRecord )

The host-defined abstract operation HostGetImportMetaProperties takes argument moduleRecord (a Module Record) and returns a List of Records with fields [[Key]] (a property key) and [[Value]] (an ECMAScript language value). 它允许宿主import.meta 返回的对象提供属性键和值。

HostGetImportMetaProperties 的默认实现是返回一个新的空 List

13.3.12.1.2 HostFinalizeImportMeta ( importMeta, moduleRecord )

The host-defined abstract operation HostFinalizeImportMeta takes arguments importMeta (an Object) and moduleRecord (a Module Record) and returns unused. 它允许宿主执行任何特殊操作,以准备从 import.meta 返回的对象。

多数宿主可以仅定义 HostGetImportMetaProperties,并让 HostFinalizeImportMeta 保持其默认行为。不过,HostFinalizeImportMeta 为需要在对象暴露给 ECMAScript 代码之前直接操作该对象的宿主提供了“逃生舱”。

HostFinalizeImportMeta 的默认实现是返回 unused

13.4 更新表达式

语法

UpdateExpression[Yield, Await] : LeftHandSideExpression[?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] ++ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] -- ++ UnaryExpression[?Yield, ?Await] -- UnaryExpression[?Yield, ?Await]

13.4.1 Static Semantics: 早期错误

UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- UpdateExpression : ++ UnaryExpression -- UnaryExpression

13.4.2 后缀递增运算符

13.4.2.1 Runtime Semantics: Evaluation

UpdateExpression : LeftHandSideExpression ++
  1. lhs 为 ? LeftHandSideExpressionEvaluation
  2. 如果 LeftHandSideExpressionAssignmentTargetTypeweb-compat,则抛出 ReferenceError 异常。
  3. oldValue 为 ? ToNumeric(? GetValue(lhs))。
  4. 如果 oldValue 是 Number,则
    1. newValueNumber::add(oldValue, 1𝔽)。
  5. 否则,
    1. 断言:oldValue 是 BigInt。
    2. newValueBigInt::add(oldValue, 1)。
  6. 执行 ? PutValue(lhs, newValue)。
  7. 返回 oldValue

13.4.3 后缀递减运算符

13.4.3.1 Runtime Semantics: Evaluation

UpdateExpression : LeftHandSideExpression --
  1. lhs 为 ? LeftHandSideExpressionEvaluation
  2. 如果 LeftHandSideExpressionAssignmentTargetTypeweb-compat,则抛出 ReferenceError 异常。
  3. oldValue 为 ? ToNumeric(? GetValue(lhs))。
  4. 如果 oldValue 是 Number,则
    1. newValueNumber::subtract(oldValue, 1𝔽)。
  5. 否则,
    1. 断言:oldValue 是 BigInt。
    2. newValueBigInt::subtract(oldValue, 1)。
  6. 执行 ? PutValue(lhs, newValue)。
  7. 返回 oldValue

13.4.4 前缀递增运算符

13.4.4.1 Runtime Semantics: Evaluation

UpdateExpression : ++ UnaryExpression
  1. expr 为 ? UnaryExpressionEvaluation
  2. 如果 UnaryExpressionAssignmentTargetTypeweb-compat,则抛出 ReferenceError 异常。
  3. oldValue 为 ? ToNumeric(? GetValue(expr))。
  4. 如果 oldValue 是 Number,则
    1. newValueNumber::add(oldValue, 1𝔽)。
  5. 否则,
    1. 断言:oldValue 是 BigInt。
    2. newValueBigInt::add(oldValue, 1)。
  6. 执行 ? PutValue(expr, newValue)。
  7. 返回 newValue

13.4.5 前缀递减运算符

13.4.5.1 Runtime Semantics: Evaluation

UpdateExpression : -- UnaryExpression
  1. expr 为 ? UnaryExpressionEvaluation
  2. 如果 UnaryExpressionAssignmentTargetTypeweb-compat,则抛出 ReferenceError 异常。
  3. oldValue 为 ? ToNumeric(? GetValue(expr))。
  4. 如果 oldValue 是 Number,则
    1. newValueNumber::subtract(oldValue, 1𝔽)。
  5. 否则,
    1. 断言:oldValue 是 BigInt。
    2. newValueBigInt::subtract(oldValue, 1)。
  6. 执行 ? PutValue(expr, newValue)。
  7. 返回 newValue

13.5 一元运算符

语法

UnaryExpression[Yield, Await] : UpdateExpression[?Yield, ?Await] delete UnaryExpression[?Yield, ?Await] void UnaryExpression[?Yield, ?Await] typeof UnaryExpression[?Yield, ?Await] + UnaryExpression[?Yield, ?Await] - UnaryExpression[?Yield, ?Await] ~ UnaryExpression[?Yield, ?Await] ! UnaryExpression[?Yield, ?Await] [+Await] CoverAwaitExpressionAndAwaitUsingDeclarationHead[?Yield] CoverAwaitExpressionAndAwaitUsingDeclarationHead[Yield] : await UnaryExpression[?Yield, +Await]

补充语法

在处理产生式
UnaryExpression : CoverAwaitExpressionAndAwaitUsingDeclarationHead
的实例时,CoverAwaitExpressionAndAwaitUsingDeclarationHead 的解释使用以下语法进行细化:

AwaitExpression[Yield] : await UnaryExpression[?Yield, +Await]

13.5.1 delete 运算符

13.5.1.1 Static Semantics: 早期错误

UnaryExpression : delete UnaryExpression Note

最后一条规则意味着,像 delete (((foo))) 这样的表达式会因为第一条规则的递归应用而产生早期错误

13.5.1.2 Runtime Semantics: Evaluation

UnaryExpression : delete UnaryExpression
  1. ref 为 ? UnaryExpressionEvaluation
  2. 如果 ref 不是 Reference Record,则返回 true
  3. 如果 IsUnresolvableReference(ref) 是 true,则
    1. 断言:ref.[[Strict]]false
    2. 返回 true
  4. 如果 IsPropertyReference(ref) 是 true,则
    1. 断言:IsPrivateReference(ref) 是 false
    2. 如果 IsSuperReference(ref) 是 true,则抛出 ReferenceError 异常。
    3. baseObj 为 ? ToObject(ref.[[Base]])。
    4. 如果 ref.[[ReferencedName]] 不是属性键,则
      1. ref.[[ReferencedName]] 设置为 ? ToPropertyKey(ref.[[ReferencedName]])。
    5. deleteStatus 为 ? baseObj.[[Delete]](ref.[[ReferencedName]])
    6. 如果 deleteStatusfalseref.[[Strict]]true,则抛出 TypeError 异常。
    7. 返回 deleteStatus
  5. baseref.[[Base]]
  6. 断言:baseEnvironment Record
  7. 返回 ? base.DeleteBinding(ref.[[ReferencedName]])
Note 1

delete 运算符出现在严格模式代码中时,如果其 UnaryExpression 是对变量、函数实参或函数名的直接引用,则会抛出 SyntaxError 异常。此外,如果 delete 运算符出现在严格模式代码中,且要删除的属性具有 { [[Configurable]]: false } 特性(或以其他方式无法删除),则会抛出 TypeError 异常。

Note 2

在步骤 4.c 中可能创建的对象,在上述抽象操作普通对象 [[Delete]] 内部方法之外不可访问。实现可以选择避免实际创建该对象。

13.5.2 void 运算符

13.5.2.1 Runtime Semantics: Evaluation

UnaryExpression : void UnaryExpression
  1. expr 为 ? UnaryExpressionEvaluation
  2. 执行 ? GetValue(expr)。
  3. 返回 undefined
Note

即使其值未被使用,也必须调用 GetValue,因为它可能具有可观察的副作用。

13.5.3 typeof 运算符

13.5.3.1 Runtime Semantics: Evaluation

UnaryExpression : typeof UnaryExpression
  1. value 为 ? UnaryExpressionEvaluation
  2. 如果 valueReference Record,则
    1. 如果 IsUnresolvableReference(value) 是 true,则返回 "undefined"
  3. value 设置为 ? GetValue(value)。
  4. 如果 valueundefined,则返回 "undefined"
  5. 如果 valuenull,则返回 "object"
  6. 如果 value 是 String,则返回 "string"
  7. 如果 value 是 Symbol,则返回 "symbol"
  8. 如果 value 是 Boolean,则返回 "boolean"
  9. 如果 value 是 Number,则返回 "number"
  10. 如果 value 是 BigInt,则返回 "bigint"
  11. 断言:value 是 Object。
  12. 如果宿主是 Web 浏览器,或以其他方式支持 [[IsHTMLDDA]] 内部槽,则
    1. 如果 value 具有 [[IsHTMLDDA]] 内部槽,则返回 "undefined"
  13. 如果 value 具有 [[Call]] 内部方法,则返回 "function"
  14. 返回 "object"

13.5.4 一元 + 运算符

Note

一元 + 运算符将其操作数转换为 Number 类型

13.5.4.1 Runtime Semantics: Evaluation

UnaryExpression : + UnaryExpression
  1. expr 为 ? UnaryExpressionEvaluation
  2. 返回 ? ToNumber(? GetValue(expr))。

13.5.5 一元 - 运算符

Note

一元 - 运算符将其操作数转换为数值,然后对其取负。对 +0𝔽 取负会产生 -0𝔽,对 -0𝔽 取负会产生 +0𝔽

13.5.5.1 Runtime Semantics: Evaluation

UnaryExpression : - UnaryExpression
  1. expr 为 ? UnaryExpressionEvaluation
  2. oldValue 为 ? ToNumeric(? GetValue(expr))。
  3. 如果 oldValue 是 Number,则返回 Number::unaryMinus(oldValue)。
  4. 断言:oldValue 是 BigInt。
  5. 返回 BigInt::unaryMinus(oldValue)。

13.5.6 按位 NOT 运算符(~

13.5.6.1 Runtime Semantics: Evaluation

UnaryExpression : ~ UnaryExpression
  1. expr 为 ? UnaryExpressionEvaluation
  2. oldValue 为 ? ToNumeric(? GetValue(expr))。
  3. 如果 oldValue 是 Number,则返回 Number::bitwiseNOT(oldValue)。
  4. 断言:oldValue 是 BigInt。
  5. 返回 BigInt::bitwiseNOT(oldValue)。

13.5.7 逻辑 NOT 运算符(!

13.5.7.1 Runtime Semantics: Evaluation

UnaryExpression : ! UnaryExpression
  1. expr 为 ? UnaryExpressionEvaluation
  2. oldValueToBoolean(? GetValue(expr))。
  3. 如果 oldValuetrue,则返回 false
  4. 返回 true

13.6 幂运算符

语法

ExponentiationExpression[Yield, Await] : UnaryExpression[?Yield, ?Await] UpdateExpression[?Yield, ?Await] ** ExponentiationExpression[?Yield, ?Await]

13.6.1 Runtime Semantics: Evaluation

ExponentiationExpression : UpdateExpression ** ExponentiationExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(UpdateExpression, **, ExponentiationExpression)。

13.7 乘法类运算符

语法

MultiplicativeExpression[Yield, Await] : ExponentiationExpression[?Yield, ?Await] MultiplicativeExpression[?Yield, ?Await] MultiplicativeOperator ExponentiationExpression[?Yield, ?Await] MultiplicativeOperator : one of * / % Note
  • * 运算符执行乘法,产生其操作数的乘积。
  • / 运算符执行除法,产生其操作数的商。
  • % 运算符从隐含的除法中产生其操作数的余数。

13.7.1 Runtime Semantics: Evaluation

MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression
  1. opText 为由 MultiplicativeOperator 匹配的源文本
  2. 返回 ? EvaluateStringOrNumericBinaryExpression(MultiplicativeExpression, opText, ExponentiationExpression)。

13.8 加性运算符

语法

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

13.8.1 加法运算符(+

Note

加法运算符执行字符串连接或数值加法。

13.8.1.1 Runtime Semantics: Evaluation

AdditiveExpression : AdditiveExpression + MultiplicativeExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(AdditiveExpression, +, MultiplicativeExpression)。

13.8.2 减法运算符(-

Note

- 运算符执行减法,产生其操作数的差。

13.8.2.1 Runtime Semantics: Evaluation

AdditiveExpression : AdditiveExpression - MultiplicativeExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(AdditiveExpression, -, MultiplicativeExpression)。

13.9 按位移位运算符

语法

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

13.9.1 左移运算符(<<

Note

按右操作数指定的数量,对左操作数执行按位左移操作。

13.9.1.1 Runtime Semantics: Evaluation

ShiftExpression : ShiftExpression << AdditiveExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(ShiftExpression, <<, AdditiveExpression)。

13.9.2 带符号右移运算符(>>

Note

按右操作数指定的数量,对左操作数执行符号填充的按位右移操作。

13.9.2.1 Runtime Semantics: Evaluation

ShiftExpression : ShiftExpression >> AdditiveExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(ShiftExpression, >>, AdditiveExpression)。

13.9.3 无符号右移运算符(>>>

Note

按右操作数指定的数量,对左操作数执行零填充的按位右移操作。

13.9.3.1 Runtime Semantics: Evaluation

ShiftExpression : ShiftExpression >>> AdditiveExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(ShiftExpression, >>>, AdditiveExpression)。

13.10 关系运算符

Note 1

求值关系运算符的结果始终是 Boolean 类型,反映由该运算符命名的关系是否在其两个操作数之间成立。

语法

RelationalExpression[In, Yield, Await] : ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] < ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] > ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] <= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] >= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] instanceof ShiftExpression[?Yield, ?Await] [+In] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression[?Yield, ?Await] [+In] PrivateIdentifier in ShiftExpression[?Yield, ?Await] Note 2

需要 [In] 语法参数,以避免将关系表达式中的 in 运算符与 for 语句中的 in 运算符混淆。

13.10.1 Runtime Semantics: Evaluation

RelationalExpression : RelationalExpression < ShiftExpression
  1. leftRef 为 ? RelationalExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? ShiftExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. result 为 ? IsLessThan(leftValue, rightValue, true)。
  6. 如果 resultundefined,则返回 false
  7. 返回 result
RelationalExpression : RelationalExpression > ShiftExpression
  1. leftRef 为 ? RelationalExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? ShiftExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. result 为 ? IsLessThan(rightValue, leftValue, false)。
  6. 如果 resultundefined,则返回 false
  7. 返回 result
RelationalExpression : RelationalExpression <= ShiftExpression
  1. leftRef 为 ? RelationalExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? ShiftExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. result 为 ? IsLessThan(rightValue, leftValue, false)。
  6. 如果 resulttrueundefined,则返回 false
  7. 返回 true
RelationalExpression : RelationalExpression >= ShiftExpression
  1. leftRef 为 ? RelationalExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? ShiftExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. result 为 ? IsLessThan(leftValue, rightValue, true)。
  6. 如果 resulttrueundefined,则返回 false
  7. 返回 true
RelationalExpression : RelationalExpression instanceof ShiftExpression
  1. leftRef 为 ? RelationalExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? ShiftExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. 返回 ? InstanceofOperator(leftValue, rightValue)。
RelationalExpression : RelationalExpression in ShiftExpression
  1. leftRef 为 ? RelationalExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? ShiftExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. 如果 rightValue 不是 Object,则抛出 TypeError 异常。
  6. 返回 ? HasProperty(rightValue, ? ToPropertyKey(leftValue))。
RelationalExpression : PrivateIdentifier in ShiftExpression
  1. privateIdentifierPrivateIdentifierStringValue
  2. rightRef 为 ? ShiftExpressionEvaluation
  3. rightValue 为 ? GetValue(rightRef)。
  4. 如果 rightValue 不是 Object,则抛出 TypeError 异常。
  5. privateEnv 为运行中的执行上下文的 PrivateEnvironment。
  6. 断言:privateEnv 不是 null
  7. privateNameResolvePrivateIdentifier(privateEnv, privateIdentifier)。
  8. 如果 PrivateElementFind(rightValue, privateName) 是 empty,则返回 false
  9. 返回 true

13.10.2 InstanceofOperator ( value, target )

The abstract operation InstanceofOperator takes arguments value (an ECMAScript language value) and target (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. 它实现用于确定 value 是否为 target 实例的通用算法:要么咨询 target%Symbol.hasInstance% 方法;如果不存在,则确定 target"prototype" 属性值是否存在于 value 的原型链中。 It performs the following steps when called:

  1. 如果 target 不是 Object,则抛出 TypeError 异常。
  2. instOfHandler 为 ? GetMethod(target, %Symbol.hasInstance%)。
  3. 如果 instOfHandler 不是 undefined,则
    1. 返回 ToBoolean(? Call(instOfHandler, target, « value »))。
  4. 如果 IsCallable(target) 是 false,则抛出 TypeError 异常。
  5. 返回 ? OrdinaryHasInstance(target, value)。
Note

步骤 45 提供与 ECMAScript 早期版本的兼容性,早期版本没有使用 %Symbol.hasInstance% 方法来定义 instanceof 运算符语义。如果对象没有定义或继承 %Symbol.hasInstance%,则使用默认的 instanceof 语义。

13.11 相等运算符

Note

求值相等运算符的结果始终是 Boolean 类型,反映由该运算符命名的关系是否在其两个操作数之间成立。

语法

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

13.11.1 Runtime Semantics: Evaluation

EqualityExpression : EqualityExpression == RelationalExpression
  1. leftRef 为 ? EqualityExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? RelationalExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. 返回 ? IsLooselyEqual(rightValue, leftValue)。
EqualityExpression : EqualityExpression != RelationalExpression
  1. leftRef 为 ? EqualityExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? RelationalExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. result 为 ? IsLooselyEqual(rightValue, leftValue)。
  6. 如果 resulttrue,则返回 false
  7. 返回 true
EqualityExpression : EqualityExpression === RelationalExpression
  1. leftRef 为 ? EqualityExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? RelationalExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. 返回 IsStrictlyEqual(rightValue, leftValue)。
EqualityExpression : EqualityExpression !== RelationalExpression
  1. leftRef 为 ? EqualityExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? RelationalExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. resultIsStrictlyEqual(rightValue, leftValue)。
  6. 如果 resulttrue,则返回 false
  7. 返回 true
Note 1

相等运算符维持以下不变量:

  • A != B 等价于 !(A == B)
  • A == B 等价于 B == A,但 AB 的求值顺序除外。
Note 2

相等运算符并不总是具有传递性。例如,可能有两个不同的 String 对象,每个都表示相同的 String 值;每个 String 对象都会被 == 运算符认为等于该 String 值,但这两个 String 对象彼此并不相等。例如:

  • new String("a") == "a""a" == new String("a") 都是 true
  • new String("a") == new String("a")false
Note 3

String 的比较使用对代码单元值序列的简单相等性测试。不会尝试使用 Unicode 规范中定义的更复杂、面向语义的字符或字符串相等性和排序顺序定义。因此,按照 Unicode 标准规范等价的 Strings 值可能会测试为不相等。实际上,此算法假定两个 Strings 都已经处于规范化形式。

13.12 二元按位运算符

语法

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

13.12.1 Runtime Semantics: Evaluation

BitwiseANDExpression : BitwiseANDExpression & EqualityExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(BitwiseANDExpression, &, EqualityExpression)。
BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(BitwiseXORExpression, ^, BitwiseANDExpression)。
BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(BitwiseORExpression, |, BitwiseXORExpression)。

13.13 二元逻辑运算符

语法

LogicalANDExpression[In, Yield, Await] : BitwiseORExpression[?In, ?Yield, ?Await] LogicalANDExpression[?In, ?Yield, ?Await] && BitwiseORExpression[?In, ?Yield, ?Await] LogicalORExpression[In, Yield, Await] : LogicalANDExpression[?In, ?Yield, ?Await] LogicalORExpression[?In, ?Yield, ?Await] || LogicalANDExpression[?In, ?Yield, ?Await] CoalesceExpression[In, Yield, Await] : CoalesceExpressionHead[?In, ?Yield, ?Await] ?? BitwiseORExpression[?In, ?Yield, ?Await] CoalesceExpressionHead[In, Yield, Await] : CoalesceExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] ShortCircuitExpression[In, Yield, Await] : LogicalORExpression[?In, ?Yield, ?Await] CoalesceExpression[?In, ?Yield, ?Await] Note

&&|| 运算符产生的值不一定是 Boolean 类型。产生的值始终是两个操作数表达式之一的值。

13.13.1 Runtime Semantics: Evaluation

LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. leftRef 为 ? LogicalANDExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. 如果 ToBoolean(leftValue) 是 false,则返回 leftValue
  4. rightRef 为 ? BitwiseORExpressionEvaluation
  5. 返回 ? GetValue(rightRef)。
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. leftRef 为 ? LogicalORExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. 如果 ToBoolean(leftValue) 是 true,则返回 leftValue
  4. rightRef 为 ? LogicalANDExpressionEvaluation
  5. 返回 ? GetValue(rightRef)。
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
  1. leftRef 为 ? CoalesceExpressionHeadEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. 如果 leftValue 既不是 undefined 也不是 null,则返回 leftValue
  4. rightRef 为 ? BitwiseORExpressionEvaluation
  5. 返回 ? GetValue(rightRef)。

13.14 条件运算符(? :

语法

ConditionalExpression[In, Yield, Await] : ShortCircuitExpression[?In, ?Yield, ?Await] ShortCircuitExpression[?In, ?Yield, ?Await] ? AssignmentExpression[+In, ?Yield, ?Await] : AssignmentExpression[?In, ?Yield, ?Await] Note

ECMAScript 中 ConditionalExpression 的语法与 C 和 Java 中的略有不同,后两者都允许第二个子表达式为 Expression,但限制第三个表达式为 ConditionalExpression。ECMAScript 中这种差异的动机是允许赋值表达式受条件表达式任一分支控制,并消除逗号表达式作为中间表达式时令人困惑且相当无用的情况。

13.14.1 Runtime Semantics: Evaluation

ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
  1. leftRef 为 ? ShortCircuitExpressionEvaluation
  2. leftValueToBoolean(? GetValue(leftRef))。
  3. 如果 leftValuetrue,则
    1. trueRef 为 ? 第一个 AssignmentExpressionEvaluation
    2. 返回 ? GetValue(trueRef)。
  4. falseRef 为 ? 第二个 AssignmentExpressionEvaluation
  5. 返回 ? GetValue(falseRef)。

13.15 赋值运算符

语法

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

13.15.1 Static Semantics: 早期错误

AssignmentExpression : LeftHandSideExpression = AssignmentExpression AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression

13.15.2 Runtime Semantics: Evaluation

AssignmentExpression : LeftHandSideExpression = AssignmentExpression
  1. 如果 LeftHandSideExpression 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. leftRef 为 ? LeftHandSideExpressionEvaluation
    2. 如果 LeftHandSideExpressionAssignmentTargetTypeweb-compat,则抛出 ReferenceError 异常。
    3. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 trueLeftHandSideExpressionIsIdentifierReftrue,则
      1. lhsLeftHandSideExpressionStringValue
      2. rightValue 为 ? 以 lhs 为实参执行 AssignmentExpressionNamedEvaluation
    4. 否则,
      1. rightRef 为 ? AssignmentExpressionEvaluation
      2. rightValue 为 ? GetValue(rightRef)。
    5. 执行 ? PutValue(leftRef, rightValue)。
    6. 返回 rightValue
  2. assignmentPattern 为由 LeftHandSideExpression 覆盖的 AssignmentPattern
  3. rightRef 为 ? AssignmentExpressionEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. 执行 ? 以 rightValue 为实参执行 assignmentPatternDestructuringAssignmentEvaluation
  6. 返回 rightValue
AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression
  1. leftRef 为 ? LeftHandSideExpressionEvaluation
  2. 如果 LeftHandSideExpressionAssignmentTargetTypeweb-compat,则抛出 ReferenceError 异常。
  3. leftValue 为 ? GetValue(leftRef)。
  4. rightRef 为 ? AssignmentExpressionEvaluation
  5. rightValue 为 ? GetValue(rightRef)。
  6. assignmentOpText 为由 AssignmentOperator 匹配的源文本
  7. opText 为下表中与 assignmentOpText 关联的 Unicode 码点序列:
    assignmentOpText opText
    **= **
    *= *
    /= /
    %= %
    += +
    -= -
    <<= <<
    >>= >>
    >>>= >>>
    &= &
    ^= ^
    |= |
  8. result 为 ? ApplyStringOrNumericBinaryOperator(leftValue, opText, rightValue)。
  9. 执行 ? PutValue(leftRef, result)。
  10. 返回 result
AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
  1. leftRef 为 ? LeftHandSideExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. 如果 ToBoolean(leftValue) 是 false,则返回 leftValue
  4. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 trueLeftHandSideExpressionIsIdentifierReftrue,则
    1. lhsLeftHandSideExpressionStringValue
    2. rightValue 为 ? 以 lhs 为实参执行 AssignmentExpressionNamedEvaluation
  5. 否则,
    1. rightRef 为 ? AssignmentExpressionEvaluation
    2. rightValue 为 ? GetValue(rightRef)。
  6. 执行 ? PutValue(leftRef, rightValue)。
  7. 返回 rightValue
AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
  1. leftRef 为 ? LeftHandSideExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. 如果 ToBoolean(leftValue) 是 true,则返回 leftValue
  4. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 trueLeftHandSideExpressionIsIdentifierReftrue,则
    1. lhsLeftHandSideExpressionStringValue
    2. rightValue 为 ? 以 lhs 为实参执行 AssignmentExpressionNamedEvaluation
  5. 否则,
    1. rightRef 为 ? AssignmentExpressionEvaluation
    2. rightValue 为 ? GetValue(rightRef)。
  6. 执行 ? PutValue(leftRef, rightValue)。
  7. 返回 rightValue
AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
  1. leftRef 为 ? LeftHandSideExpressionEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. 如果 leftValue 既不是 undefined 也不是 null,则返回 leftValue
  4. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 trueLeftHandSideExpressionIsIdentifierReftrue,则
    1. lhsLeftHandSideExpressionStringValue
    2. rightValue 为 ? 以 lhs 为实参执行 AssignmentExpressionNamedEvaluation
  5. 否则,
    1. rightRef 为 ? AssignmentExpressionEvaluation
    2. rightValue 为 ? GetValue(rightRef)。
  6. 执行 ? PutValue(leftRef, rightValue)。
  7. 返回 rightValue
Note

当此表达式出现在严格模式代码中时,如果步骤 1.e3222 中的 leftRef 是无法解析的引用,则为运行时错误。如果是这种情况,则会抛出 ReferenceError 异常。此外,如果步骤 9666 中的 leftRef 是对特性值为 { [[Writable]]: false } 的数据属性、特性值为 { [[Set]]: undefined } 的访问器属性,或对 IsExtensible 谓词返回值为 false 的对象的不存在属性的引用,则为运行时错误。在这些情况下会抛出 TypeError 异常。

13.15.3 ApplyStringOrNumericBinaryOperator ( leftValue, opText, rightValue )

The abstract operation ApplyStringOrNumericBinaryOperator takes arguments leftValue (an ECMAScript language value), opText (**, *, /, %, +, -, <<, >>, >>>, &, ^, or |), and rightValue (an ECMAScript language value) and returns either a normal completion containing either a String, a BigInt, or a Number, or a throw completion. It performs the following steps when called:

  1. 如果 opText+,则
    1. leftPrimitive 为 ? ToPrimitive(leftValue)。
    2. rightPrimitive 为 ? ToPrimitive(rightValue)。
    3. 如果 leftPrimitive 是 String 或 rightPrimitive 是 String,则
      1. leftString 为 ? ToString(leftPrimitive)。
      2. rightString 为 ? ToString(rightPrimitive)。
      3. 返回 leftStringrightString字符串连接
    4. leftValue 设置为 leftPrimitive
    5. rightValue 设置为 rightPrimitive
  2. 注:在此处,它必须是数值操作。
  3. leftNumber 为 ? ToNumeric(leftValue)。
  4. rightNumber 为 ? ToNumeric(rightValue)。
  5. 如果 SameType(leftNumber, rightNumber) 是 false,则抛出 TypeError 异常。
  6. 如果 leftNumber 是 BigInt,则
    1. 如果 opText**,则返回 ? BigInt::exponentiate(leftNumber, rightNumber)。
    2. 如果 opText/,则返回 ? BigInt::divide(leftNumber, rightNumber)。
    3. 如果 opText%,则返回 ? BigInt::remainder(leftNumber, rightNumber)。
    4. 如果 opText>>>,则返回 ? BigInt::unsignedRightShift(leftNumber, rightNumber)。
    5. operation 为下表中与 opText 关联的抽象操作
      opText operation
      * BigInt::multiply
      + BigInt::add
      - BigInt::subtract
      << BigInt::leftShift
      >> BigInt::signedRightShift
      & BigInt::bitwiseAND
      ^ BigInt::bitwiseXOR
      | BigInt::bitwiseOR
  7. 否则,
    1. 断言:leftNumber 是 Number。
    2. operation 为下表中与 opText 关联的抽象操作
      opText operation
      ** Number::exponentiate
      * Number::multiply
      / Number::divide
      % Number::remainder
      + Number::add
      - Number::subtract
      << Number::leftShift
      >> Number::signedRightShift
      >>> Number::unsignedRightShift
      & Number::bitwiseAND
      ^ Number::bitwiseXOR
      | Number::bitwiseOR
  8. 返回 operation(leftNumber, rightNumber)。
Note 1

在步骤 1.a1.b 中调用 ToPrimitive 时不提供 hint。除 Dates 外的所有标准对象都会像给出了 number 一样处理没有 hint 的情况;Dates 会像给出了 string 一样处理没有 hint 的情况。异质对象可以以其他某种方式处理没有 hint 的情况。

Note 2

步骤 1.cIsLessThan 算法的步骤 3 不同,因为它使用逻辑或操作,而不是逻辑与操作。

13.15.4 EvaluateStringOrNumericBinaryExpression ( leftOperand, opText, rightOperand )

The abstract operation EvaluateStringOrNumericBinaryExpression takes arguments leftOperand (a Parse Node), opText (**, *, /, %, +, -, <<, >>, >>>, &, ^, or |), and rightOperand (a Parse Node) and returns either a normal completion containing either a String, a BigInt, or a Number, or an abrupt completion. It performs the following steps when called:

  1. leftRef 为 ? leftOperandEvaluation
  2. leftValue 为 ? GetValue(leftRef)。
  3. rightRef 为 ? rightOperandEvaluation
  4. rightValue 为 ? GetValue(rightRef)。
  5. 返回 ? ApplyStringOrNumericBinaryOperator(leftValue, opText, rightValue)。

13.15.5 解构赋值

补充语法

在某些情况下,当处理产生式的实例
AssignmentExpression : LeftHandSideExpression = AssignmentExpression
时,使用以下语法细化 LeftHandSideExpression 的解释:

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

13.15.5.1 Static Semantics: 早期错误

AssignmentProperty : IdentifierReference Initializeropt AssignmentRestProperty : ... DestructuringAssignmentTarget DestructuringAssignmentTarget : LeftHandSideExpression

13.15.5.2 Runtime Semantics: DestructuringAssignmentEvaluation

The syntax-directed operation DestructuringAssignmentEvaluation takes argument value (an ECMAScript language value) and returns either a normal completion containing unused or an abrupt completion. It is defined piecewise over the following productions:

ObjectAssignmentPattern : { }
  1. 执行 ? RequireObjectCoercible(value)。
  2. 返回 unused
ObjectAssignmentPattern : { AssignmentPropertyList } { AssignmentPropertyList , }
  1. 执行 ? RequireObjectCoercible(value)。
  2. 执行 ? 以 value 为实参执行 AssignmentPropertyListPropertyDestructuringAssignmentEvaluation
  3. 返回 unused
ObjectAssignmentPattern : { AssignmentRestProperty }
  1. 执行 ? RequireObjectCoercible(value)。
  2. excludedNames 为新的空 List
  3. 返回 ? 以 valueexcludedNames 为实参执行 AssignmentRestPropertyRestDestructuringAssignmentEvaluation
ObjectAssignmentPattern : { AssignmentPropertyList , AssignmentRestProperty }
  1. 执行 ? RequireObjectCoercible(value)。
  2. excludedNames 为 ? 以 value 为实参执行 AssignmentPropertyListPropertyDestructuringAssignmentEvaluation
  3. 返回 ? 以 valueexcludedNames 为实参执行 AssignmentRestPropertyRestDestructuringAssignmentEvaluation
ArrayAssignmentPattern : [ ]
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. 返回 ? IteratorClose(iteratorRecord, NormalCompletion(unused))。
ArrayAssignmentPattern : [ Elision ]
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. resultCompletion(以 iteratorRecord 为实参执行 ElisionIteratorDestructuringAssignmentEvaluation)。
  3. 如果 iteratorRecord.[[Done]]false,则返回 ? IteratorClose(iteratorRecord, result)。
  4. 返回 result
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. 如果存在 Elision,则
    1. statusCompletion(以 iteratorRecord 为实参执行 ElisionIteratorDestructuringAssignmentEvaluation)。
    2. 如果 status 是 abrupt completion,则
      1. 断言:iteratorRecord.[[Done]]true
      2. 返回 ? status
  3. resultCompletion(以 iteratorRecord 为实参执行 AssignmentRestElementIteratorDestructuringAssignmentEvaluation)。
  4. 如果 iteratorRecord.[[Done]]false,则返回 ? IteratorClose(iteratorRecord, result)。
  5. 返回 result
ArrayAssignmentPattern : [ AssignmentElementList ]
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. resultCompletion(以 iteratorRecord 为实参执行 AssignmentElementListIteratorDestructuringAssignmentEvaluation)。
  3. 如果 iteratorRecord.[[Done]]false,则返回 ? IteratorClose(iteratorRecord, result)。
  4. 返回 result
ArrayAssignmentPattern : [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. statusCompletion(以 iteratorRecord 为实参执行 AssignmentElementListIteratorDestructuringAssignmentEvaluation)。
  3. 如果 status 是 abrupt completion,则
    1. 如果 iteratorRecord.[[Done]]false,则返回 ? IteratorClose(iteratorRecord, status)。
    2. 返回 ? status
  4. 如果存在 Elision,则
    1. status 设置为 Completion(以 iteratorRecord 为实参执行 ElisionIteratorDestructuringAssignmentEvaluation)。
    2. 如果 status 是 abrupt completion,则
      1. 断言:iteratorRecord.[[Done]]true
      2. 返回 ? status
  5. 如果存在 AssignmentRestElement,则
    1. status 设置为 Completion(以 iteratorRecord 为实参执行 AssignmentRestElementIteratorDestructuringAssignmentEvaluation)。
  6. 如果 iteratorRecord.[[Done]]false,则返回 ? IteratorClose(iteratorRecord, status)。
  7. 返回 ? status

13.15.5.3 Runtime Semantics: PropertyDestructuringAssignmentEvaluation

The syntax-directed operation PropertyDestructuringAssignmentEvaluation takes argument value (an ECMAScript language value) and returns either a normal completion containing a List of property keys or an abrupt completion. 它收集所有被解构属性键的列表。 It is defined piecewise over the following productions:

AssignmentPropertyList : AssignmentPropertyList , AssignmentProperty
  1. propertyNames 为 ? 以 value 为实参执行 AssignmentPropertyListPropertyDestructuringAssignmentEvaluation
  2. nextNames 为 ? 以 value 为实参执行 AssignmentPropertyPropertyDestructuringAssignmentEvaluation
  3. 返回 propertyNamesnextNames列表连接
AssignmentProperty : IdentifierReference Initializeropt
  1. propertyNameIdentifierReferenceStringValue
  2. leftRef 为 ? ResolveBinding(propertyName)。
  3. value 设置为 ? GetV(value, propertyName)。
  4. 如果存在 Initializervalueundefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true,则
      1. value 设置为 ? 以 propertyName 为实参执行 InitializerNamedEvaluation
    2. 否则,
      1. defaultValue 为 ? InitializerEvaluation
      2. value 设置为 ? GetValue(defaultValue)。
  5. 执行 ? PutValue(leftRef, value)。
  6. 返回 « propertyName »。
AssignmentProperty : PropertyName : AssignmentElement
  1. name 为 ? PropertyNameEvaluation
  2. 执行 ? 以 valuename 为实参执行 AssignmentElementKeyedDestructuringAssignmentEvaluation
  3. 返回 « name »。

13.15.5.4 Runtime Semantics: RestDestructuringAssignmentEvaluation

The syntax-directed operation RestDestructuringAssignmentEvaluation takes arguments value (an ECMAScript language value) and excludedNames (a List of property keys) and returns either a normal completion containing unused or an abrupt completion. It is defined piecewise over the following productions:

AssignmentRestProperty : ... DestructuringAssignmentTarget
  1. leftRef 为 ? DestructuringAssignmentTargetEvaluation
  2. restObjOrdinaryObjectCreate(%Object.prototype%)。
  3. 执行 ? CopyDataProperties(restObj, value, excludedNames)。
  4. 返回 ? PutValue(leftRef, restObj)。

13.15.5.5 Runtime Semantics: IteratorDestructuringAssignmentEvaluation

The syntax-directed operation IteratorDestructuringAssignmentEvaluation takes argument iteratorRecord (an Iterator Record) and returns either a normal completion containing unused or an abrupt completion. It is defined piecewise over the following productions:

AssignmentElementList : AssignmentElisionElement
  1. 返回 ? 以 iteratorRecord 为实参执行 AssignmentElisionElementIteratorDestructuringAssignmentEvaluation
AssignmentElementList : AssignmentElementList , AssignmentElisionElement
  1. 执行 ? 以 iteratorRecord 为实参执行 AssignmentElementListIteratorDestructuringAssignmentEvaluation
  2. 返回 ? 以 iteratorRecord 为实参执行 AssignmentElisionElementIteratorDestructuringAssignmentEvaluation
AssignmentElisionElement : AssignmentElement
  1. 返回 ? 以 iteratorRecord 为实参执行 AssignmentElementIteratorDestructuringAssignmentEvaluation
AssignmentElisionElement : Elision AssignmentElement
  1. 执行 ? 以 iteratorRecord 为实参执行 ElisionIteratorDestructuringAssignmentEvaluation
  2. 返回 ? 以 iteratorRecord 为实参执行 AssignmentElementIteratorDestructuringAssignmentEvaluation
Elision : ,
  1. 如果 iteratorRecord.[[Done]]false,则
    1. 执行 ? IteratorStep(iteratorRecord)。
  2. 返回 unused
Elision : Elision ,
  1. 执行 ? 以 iteratorRecord 为实参执行 ElisionIteratorDestructuringAssignmentEvaluation
  2. 如果 iteratorRecord.[[Done]]false,则
    1. 执行 ? IteratorStep(iteratorRecord)。
  3. 返回 unused
AssignmentElement : DestructuringAssignmentTarget Initializeropt
  1. 如果 DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. leftRef 为 ? DestructuringAssignmentTargetEvaluation
  2. valueundefined
  3. 如果 iteratorRecord.[[Done]]false,则
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 next 不是 done,则
      1. value 设置为 next
  4. 如果存在 Initializervalueundefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 是 trueDestructuringAssignmentTargetIsIdentifierReftrue,则
      1. targetDestructuringAssignmentTargetStringValue
      2. v 为 ? 以 target 为实参执行 InitializerNamedEvaluation
    2. 否则,
      1. defaultValue 为 ? InitializerEvaluation
      2. v 为 ? GetValue(defaultValue)。
  5. 否则,
    1. vvalue
  6. 如果 DestructuringAssignmentTargetObjectLiteralArrayLiteral,则
    1. nestedAssignmentPattern 为由 DestructuringAssignmentTarget 覆盖的 AssignmentPattern
    2. 返回 ? 以 v 为实参执行 nestedAssignmentPatternDestructuringAssignmentEvaluation
  7. 返回 ? PutValue(leftRef, v)。
Note

通过在访问迭代器或求值 Initializer 之前求值不是解构模式的 DestructuringAssignmentTarget,来维持从左到右的求值顺序。

AssignmentRestElement : ... DestructuringAssignmentTarget
  1. 如果 DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. leftRef 为 ? DestructuringAssignmentTargetEvaluation
  2. array 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. 重复,当 iteratorRecord.[[Done]]false 时,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 next 不是 done,则
      1. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(n)), next)。
      2. n 设置为 n + 1。
  5. 如果 DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. 返回 ? PutValue(leftRef, array)。
  6. nestedAssignmentPattern 为由 DestructuringAssignmentTarget 覆盖的 AssignmentPattern
  7. 返回 ? 以 array 为实参执行 nestedAssignmentPatternDestructuringAssignmentEvaluation

13.15.5.6 Runtime Semantics: KeyedDestructuringAssignmentEvaluation

The syntax-directed operation KeyedDestructuringAssignmentEvaluation takes arguments value (an ECMAScript language value) and propertyName (a property key) and returns either a normal completion containing unused or an abrupt completion. It is defined piecewise over the following productions:

AssignmentElement : DestructuringAssignmentTarget Initializeropt
  1. 如果 DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. leftRef 为 ? DestructuringAssignmentTargetEvaluation
  2. value 设置为 ? GetV(value, propertyName)。
  3. 如果存在 Initializervalueundefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 是 trueDestructuringAssignmentTargetIsIdentifierReftrue,则
      1. targetDestructuringAssignmentTargetStringValue
      2. rhsValue 为 ? 以 target 为实参执行 InitializerNamedEvaluation
    2. 否则,
      1. defaultValue 为 ? InitializerEvaluation
      2. rhsValue 为 ? GetValue(defaultValue)。
  4. 否则,
    1. rhsValuevalue
  5. 如果 DestructuringAssignmentTargetObjectLiteralArrayLiteral,则
    1. assignmentPattern 为由 DestructuringAssignmentTarget 覆盖的 AssignmentPattern
    2. 返回 ? 以 rhsValue 为实参执行 assignmentPatternDestructuringAssignmentEvaluation
  6. 返回 ? PutValue(leftRef, rhsValue)。

13.16 逗号运算符(,

语法

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

13.16.1 Runtime Semantics: Evaluation

Expression : Expression , AssignmentExpression
  1. leftRef 为 ? ExpressionEvaluation
  2. 执行 ? GetValue(leftRef)。
  3. rightRef 为 ? AssignmentExpressionEvaluation
  4. 返回 ? GetValue(rightRef)。
Note

即使其值未被使用,也必须调用 GetValue,因为它可能具有可观察的副作用。