页面模式偏好

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 注

文法中允许 yield 和 await 作为 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] 参数,并且 Identifier 的 StringValue 是 "yield",则为语法错误。
  • 如果此产生式具有 [Await] 参数,并且 Identifier 的 StringValue 是 "await",则为语法错误。
Identifier : IdentifierName but not ReservedWord 注

IdentifierName 的 StringValue 会规范化 IdentifierName 中的任何 Unicode 转义序列,因此不能使用此类转义来书写一个码点序列与 ReservedWord 相同的 Identifier。

13.1.2 Static Semantics: StringValue

语法制导操作 StringValue,接收无参数;返回值:String。 它按以下产生式分别定义:

IdentifierName :: IdentifierStart IdentifierName IdentifierPart
  1. 令 nameUnescaped 为 IdentifierName 的 IdentifierCodePoints。
  2. 返回 CodePointsToString(nameUnescaped)。
IdentifierReference : yield BindingIdentifier : yield LabelIdentifier : yield
  1. 返回 "yield"。
IdentifierReference : await BindingIdentifier : await LabelIdentifier : await
  1. 返回 "await"。
Identifier : IdentifierName but not ReservedWord
  1. 返回 IdentifierName 的 StringValue。
PrivateIdentifier :: # IdentifierName
  1. 返回 0x0023 (NUMBER SIGN) 和 IdentifierName 的 StringValue 的字符串连接。
ModuleExportName : StringLiteral
  1. 返回 StringLiteral 的 SV。

13.1.3 Runtime Semantics: Evaluation

IdentifierReference : Identifier
  1. 返回 ? ResolveBinding(Identifier 的 StringValue)。
IdentifierReference : yield
  1. 返回 ? ResolveBinding("yield")。
IdentifierReference : await
  1. 返回 ? ResolveBinding("await")。
注 1

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

注 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] ,opt ) ( ... 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 是标记 false,则返回 false。
  2. 如果 BooleanLiteral 是标记 true,则返回 true。
Literal : NumericLiteral
  1. 返回 12.9.3 中定义的 NumericLiteral 的 NumericValue。
Literal : StringLiteral
  1. 返回 12.9.4.2 中定义的 StringLiteral 的 SV。

13.2.4 Array 初始化器

注

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

语法制导操作 ArrayAccumulation,接收参数 array (Array) 和 nextIndex (整数);返回值:(正常完成 (值:整数) 或 突兀完成)。 它按以下产生式分别定义:

Elision : ,
  1. 令 length 为 nextIndex + 1。
  2. 执行 ? Set(array, "length", 𝔽(length), true)。
  3. 注:如果 length 超过 232 - 1,则上述步骤会抛出异常。
  4. 返回 length。
Elision : Elision ,
  1. 返回 ? 以 array 和 (nextIndex + 1) 为参数对 Elision 执行 ArrayAccumulation 的结果。
ElementList : Elisionopt AssignmentExpression
  1. 如果存在 Elision,则
    1. 将 nextIndex 设置为 ? 以 array 和 nextIndex 为参数对 Elision 执行 ArrayAccumulation 的结果。
  2. 令 initResult 为 ? AssignmentExpression 的 Evaluation。
  3. 令 initValue 为 ? GetValue(initResult)。
  4. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue)。
  5. 返回 nextIndex + 1。
ElementList : Elisionopt SpreadElement
  1. 如果存在 Elision,则
    1. 将 nextIndex 设置为 ? 以 array 和 nextIndex 为参数对 Elision 执行 ArrayAccumulation 的结果。
  2. 返回 ? 以 array 和 nextIndex 为参数对 SpreadElement 执行 ArrayAccumulation 的结果。
ElementList : ElementList , Elisionopt AssignmentExpression
  1. 将 nextIndex 设置为 ? 以 array 和 nextIndex 为参数对派生的 ElementList 执行 ArrayAccumulation 的结果。
  2. 如果存在 Elision,则
    1. 将 nextIndex 设置为 ? 以 array 和 nextIndex 为参数对 Elision 执行 ArrayAccumulation 的结果。
  3. 令 initResult 为 ? AssignmentExpression 的 Evaluation。
  4. 令 initValue 为 ? GetValue(initResult)。
  5. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue)。
  6. 返回 nextIndex + 1。
ElementList : ElementList , Elisionopt SpreadElement
  1. 将 nextIndex 设置为 ? 以 array 和 nextIndex 为参数对派生的 ElementList 执行 ArrayAccumulation 的结果。
  2. 如果存在 Elision,则
    1. 将 nextIndex 设置为 ? 以 array 和 nextIndex 为参数对 Elision 执行 ArrayAccumulation 的结果。
  3. 返回 ? 以 array 和 nextIndex 为参数对 SpreadElement 执行 ArrayAccumulation 的结果。
SpreadElement : ... AssignmentExpression
  1. 令 spreadRef 为 ? AssignmentExpression 的 Evaluation。
  2. 令 spreadObj 为 ? GetValue(spreadRef)。
  3. 令 iteratorRecord 为 ? GetIterator(spreadObj, sync)。
  4. 重复执行,
    1. 令 next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 next 是 done,则返回 nextIndex。
    3. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), next)。
    4. 将 nextIndex 设置为 nextIndex + 1。
注

使用 CreateDataPropertyOrThrow 是为了确保即使标准内置 Array 原型对象已被修改,以致无法使用 [[Set]] 创建新的自有属性,仍会为数组定义自有属性。

13.2.4.2 Runtime Semantics: Evaluation

ArrayLiteral : [ Elisionopt ]
  1. 令 array 为 ! ArrayCreate(0)。
  2. 如果存在 Elision,则
    1. 执行 ? 以 array 和 0 为参数对 Elision 执行 ArrayAccumulation。
  3. 返回 array。
ArrayLiteral : [ ElementList ]
  1. 令 array 为 ! ArrayCreate(0)。
  2. 执行 ? 以 array 和 0 为参数对 ElementList 执行 ArrayAccumulation。
  3. 返回 array。
ArrayLiteral : [ ElementList , Elisionopt ]
  1. 令 array 为 ! ArrayCreate(0)。
  2. 令 nextIndex 为 ? 以 array 和 0 为参数对 ElementList 执行 ArrayAccumulation 的结果。
  3. 如果存在 Elision,则
    1. 执行 ? 以 array 和 nextIndex 为参数对 Elision 执行 ArrayAccumulation。
  4. 返回 array。

13.2.5 对象初始化器

注 1

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

语法

ObjectLiteral[Yield, Await] : { } { PropertyDefinitionList[?Yield, ?Await] ,opt } 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] 注 2

MethodDefinition 定义于 15.4。

注 3

有关 CoverInitializedName 的意义,参见下一节。

13.2.5.1 Static Semantics: 提前错误

ObjectLiteral : { PropertyDefinitionList ,opt } 注 1

PropertyNameList 返回的 List 不包括使用 ComputedPropertyName 定义的属性名称。

PropertyDefinition : MethodDefinition PropertyDefinition : CoverInitializedName
  • 如果有任何源文本被此产生式匹配,则为语法错误。
注 2

本规范其他位置存在提前错误规则,在某些情况下要求 LeftHandSideExpression 必须覆盖一个 AssignmentPattern。因此,ObjectLiteral 充当 ObjectAssignmentPattern 的覆盖文法。CoverInitializedName 产生式是完整覆盖 AssignmentProperty 所必需的,但在实际对象初始化器中无效。

具体而言,在期望实际 ObjectLiteral 的上下文中,上述提前错误规则会阻止使用 CoverInitializedName。但在 ObjectLiteral 被用作覆盖文法的情况下,“必须覆盖”的语义规定 ObjectLiteral 内的 Parse Node 不受提前错误规则约束,因此允许 CoverInitializedName。

例如,考虑:

let o = {f = 1};

{f = 1} 被解析为带有 CoverInitializedName 的 ObjectLiteral,因而通过此提前错误规则产生语法错误。

相比之下,考虑:

({f = 1} = {f: 2});

这里,{f = 1} 最初同样被解析为带有 CoverInitializedName 的 ObjectLiteral,但由于它是 AssignmentExpression 的 LeftHandSideExpression,所以必须覆盖一个 AssignmentPattern,因此 ObjectLiteral 和 CoverInitializedName 不受提前错误规则约束。相反,{f = 1} 会被重新解析为带有 AssignmentProperty 的 ObjectAssignmentPattern,并且不存在语法错误。

13.2.5.2 Static Semantics: IsComputedPropertyKey

语法制导操作 IsComputedPropertyKey,接收无参数;返回值:Boolean。 它按以下产生式分别定义:

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

13.2.5.3 Static Semantics: PropertyDefinitionNodes

语法制导操作 PropertyDefinitionNodes,接收无参数;返回值:列表 (元素:解析节点)。 它按以下产生式分别定义:

ObjectLiteral : { }
  1. 返回新的空 List。
PropertyDefinitionList : PropertyDefinition
  1. 返回 « PropertyDefinition »。
PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. 令 head 为派生的 PropertyDefinitionList 的 PropertyDefinitionNodes。
  2. 返回 head 与 « PropertyDefinition » 的列表连接。

13.2.5.4 Static Semantics: PropertyNameList

语法制导操作 PropertyNameList,接收无参数;返回值:列表 (元素:String)。 它按以下产生式分别定义:

PropertyDefinitionList : PropertyDefinition
  1. 令 propertyName 为 PropertyDefinition 的 PropName。
  2. 如果 propertyName 是 empty,则返回新的空 List。
  3. 返回 « propertyName »。
PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. 令 list 为 PropertyDefinitionList 的 PropertyNameList。
  2. 令 propertyName 为 PropertyDefinition 的 PropName。
  3. 如果 propertyName 是 empty,则返回 list。
  4. 返回 list 与 « propertyName » 的列表连接。

13.2.5.5 Runtime Semantics: Evaluation

ObjectLiteral : { }
  1. 返回 OrdinaryObjectCreate(%Object.prototype%)。
ObjectLiteral : { PropertyDefinitionList ,opt }
  1. 令 obj 为 OrdinaryObjectCreate(%Object.prototype%)。
  2. 执行 ? 以 obj 为参数对 PropertyDefinitionList 执行 PropertyDefinitionEvaluation。
  3. 返回 obj。
LiteralPropertyName : IdentifierName
  1. 返回 IdentifierName 的 StringValue。
LiteralPropertyName : StringLiteral
  1. 返回 StringLiteral 的 SV。
LiteralPropertyName : NumericLiteral
  1. 令 number 为 NumericLiteral 的 NumericValue。
  2. 返回 ! ToString(number)。
ComputedPropertyName : [ AssignmentExpression ]
  1. 令 exprValue 为 ? AssignmentExpression 的 Evaluation。
  2. 令 propertyName 为 ? GetValue(exprValue)。
  3. 返回 ? ToPropertyKey(propertyName)。

13.2.5.6 Runtime Semantics: PropertyDefinitionEvaluation

语法制导操作 PropertyDefinitionEvaluation,接收参数 obj (Object);返回值:(正常完成 (值:unused) 或 突兀完成)。 它按以下产生式分别定义:

PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. 执行 ? 以 obj 为参数对 PropertyDefinitionList 执行 PropertyDefinitionEvaluation。
  2. 执行 ? 以 obj 为参数对 PropertyDefinition 执行 PropertyDefinitionEvaluation。
  3. 返回 unused。
PropertyDefinition : ... AssignmentExpression
  1. 令 exprValue 为 ? AssignmentExpression 的 Evaluation。
  2. 令 fromValue 为 ? GetValue(exprValue)。
  3. 令 excludedNames 为新的空 List。
  4. 执行 ? CopyDataProperties(obj, fromValue, excludedNames)。
  5. 返回 unused。
PropertyDefinition : IdentifierReference
  1. 令 propertyName 为 IdentifierReference 的 StringValue。
  2. 令 exprValue 为 ? IdentifierReference 的 Evaluation。
  3. 令 propertyValue 为 ? GetValue(exprValue)。
  4. 断言:obj 是没有不可配置属性的普通、可扩展对象。
  5. 执行 ! CreateDataPropertyOrThrow(obj, propertyName, propertyValue)。
  6. 返回 unused。
PropertyDefinition : PropertyName : AssignmentExpression
  1. 令 propertyKey 为 ? PropertyName 的 Evaluation。
  2. 如果此 PropertyDefinition 包含在正为 ParseJSON 求值的 Script 中(参见 ParseJSON 的步骤 6),则
    1. 令 isProtoSetter 为 false。
  3. 否则,如果 propertyKey 是 "__proto__" 且 PropertyName 的 IsComputedPropertyKey 是 false,则
    1. 令 isProtoSetter 为 true。
  4. 否则,
    1. 令 isProtoSetter 为 false。
  5. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 true 且 isProtoSetter 是 false,则
    1. 令 propertyValue 为 ? 以 propertyKey 为参数对 AssignmentExpression 执行 NamedEvaluation 的结果。
  6. 否则,
    1. 令 exprValueRef 为 ? AssignmentExpression 的 Evaluation。
    2. 令 propertyValue 为 ? GetValue(exprValueRef)。
  7. 如果 isProtoSetter 是 true,则
    1. 如果 propertyValue 是 Object 或 propertyValue 是 null,则
      1. 执行 ! obj.[[SetPrototypeOf]](propertyValue)。
    2. 返回 unused。
  8. 断言:obj 是没有不可配置属性的普通、可扩展对象。
  9. 执行 ! CreateDataPropertyOrThrow(obj, propertyKey, propertyValue)。
  10. 返回 unused。
PropertyDefinition : MethodDefinition
  1. 令 result 为 ? 以 obj 和 true 为参数对 MethodDefinition 执行 MethodDefinitionEvaluation 的结果。
  2. 断言:result 是 empty。
  3. 返回 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 )

抽象操作 IsValidRegularExpressionLiteral,接收参数 literal (a RegularExpressionLiteral Parse Node);返回值:Boolean。 它确定其参数是否为有效的正则表达式字面量。 调用时执行以下步骤:

  1. 令 flags 为 literal 的 FlagText。
  2. 如果 flags 包含 d、g、i、m、s、u、v 或 y 之外的任何码点,则返回 false。
  3. 如果 flags 中任何码点出现超过一次,则返回 false。
  4. 如果 flags 包含 u,则令 u 为 true;否则令 u 为 false。
  5. 如果 flags 包含 v,则令 v 为 true;否则令 v 为 false。
  6. 令 patternText 为 literal 的 BodyText。
  7. 如果 u 是 false 且 v 是 false,则
    1. 令 stringValue 为 CodePointsToString(patternText)。
    2. 将 patternText 设置为这样得到的码点序列:把 stringValue 的每个 16 位元素解释为一个 Unicode BMP 码点。不会对这些元素应用 UTF-16 解码。
  8. 令 parseResult 为 ParsePattern(patternText, u, v)。
  9. 如果 parseResult 是 Parse Node,则返回 true。
  10. 返回 false。

13.2.7.3 Runtime Semantics: Evaluation

PrimaryExpression : RegularExpressionLiteral
  1. 令 pattern 为 CodePointsToString(RegularExpressionLiteral 的 BodyText)。
  2. 令 flags 为 CodePointsToString(RegularExpressionLiteral 的 FlagText)。
  3. 返回 ! RegExpCreate(pattern, flags)。

13.2.8 模板字面量

语法

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

13.2.8.1 Static Semantics: 提前错误

TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate TemplateLiteral[Yield, Await, Tagged] : SubstitutionTemplate[?Yield, ?Await]

13.2.8.2 Static Semantics: TemplateStrings

语法制导操作 TemplateStrings,接收参数 escapes ((raw 或 cooked));返回值:列表 (元素:(String 或 undefined))。 它按以下产生式分别定义:

TemplateLiteral : NoSubstitutionTemplate
  1. 返回 « TemplateString(NoSubstitutionTemplate, escapes) »。
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. 令 head 为 « TemplateString(TemplateHead, escapes) »。
  2. 令 tail 为以 escapes 为参数对 TemplateSpans 执行 TemplateStrings 的结果。
  3. 返回 head 和 tail 的列表连接。
TemplateSpans : TemplateTail
  1. 返回 « TemplateString(TemplateTail, escapes) »。
TemplateSpans : TemplateMiddleList TemplateTail
  1. 令 middle 为以 escapes 为参数对 TemplateMiddleList 执行 TemplateStrings 的结果。
  2. 令 tail 为 « TemplateString(TemplateTail, escapes) »。
  3. 返回 middle 和 tail 的列表连接。
TemplateMiddleList : TemplateMiddle Expression
  1. 返回 « TemplateString(TemplateMiddle, escapes) »。
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. 令 front 为以 escapes 为参数对 TemplateMiddleList 执行 TemplateStrings 的结果。
  2. 令 last 为 « TemplateString(TemplateMiddle, escapes) »。
  3. 返回 front 和 last 的列表连接。

13.2.8.3 Static Semantics: TemplateString ( templateToken, escapes )

抽象操作 TemplateString,接收参数 templateToken ((a NoSubstitutionTemplate Parse Node、a TemplateHead Parse Node、a TemplateMiddle Parse Node 或 a TemplateTail Parse Node)) 和 escapes ((raw 或 cooked));返回值:(String 或 undefined)。 调用时执行以下步骤:

  1. 如果 escapes 是 raw,则返回 templateToken 的 TRV。
  2. 返回 templateToken 的 TV。
注

如果 escapes 是 raw 且 templateToken 包含 NotEscapeSequence,此操作返回 undefined。在所有其他情况下,它返回 String。

13.2.8.4 GetTemplateObject ( templateLiteral )

抽象操作 GetTemplateObject,接收参数 templateLiteral (解析节点);返回值:Array。 调用时执行以下步骤:

  1. 令 realm 为当前 Realm Record。
  2. 令 templateRegistry 为 realm.[[TemplateMap]]。
  3. 对 templateRegistry 的每个元素 element,执行
    1. 如果 element.[[Site]] 与 templateLiteral 是同一个 Parse Node,则
      1. 返回 element.[[Array]]。
  4. 令 rawStrings 为以 raw 为参数对 templateLiteral 执行 TemplateStrings 的结果。
  5. 断言:rawStrings 是 String 的 List。
  6. 令 cookedStrings 为以 cooked 为参数对 templateLiteral 执行 TemplateStrings 的结果。
  7. 令 count 为 List cookedStrings 中的元素数量。
  8. 断言:count ≤ 232 - 1。
  9. 令 template 为 ! ArrayCreate(count)。
  10. 令 rawObj 为 ! ArrayCreate(count)。
  11. 令 index 为 0。
  12. 当 index < count 时,重复执行,
    1. 令 propertyKey 为 ! ToString(𝔽(index))。
    2. 令 cookedValue 为 cookedStrings[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。
注 1

创建模板对象不会产生突然完成。

注 2

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

注 3

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

13.2.8.5 Runtime Semantics: SubstitutionEvaluation

语法制导操作 SubstitutionEvaluation,接收无参数;返回值:(正常完成 (值:列表 (元素:ECMAScript 语言值)) 或 突兀完成)。 它按以下产生式分别定义:

TemplateSpans : TemplateTail
  1. 返回新的空 List。
TemplateSpans : TemplateMiddleList TemplateTail
  1. 返回 ? TemplateMiddleList 的 SubstitutionEvaluation。
TemplateMiddleList : TemplateMiddle Expression
  1. 令 subRef 为 ? Expression 的 Evaluation。
  2. 令 sub 为 ? GetValue(subRef)。
  3. 返回 « sub »。
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. 令 preceding 为 ? TemplateMiddleList 的 SubstitutionEvaluation。
  2. 令 nextRef 为 ? Expression 的 Evaluation。
  3. 令 next 为 ? GetValue(nextRef)。
  4. 返回 preceding 与 « next » 的列表连接。

13.2.8.6 Runtime Semantics: Evaluation

TemplateLiteral : NoSubstitutionTemplate
  1. 返回 12.9.6 中定义的 NoSubstitutionTemplate 的 TV。
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. 令 head 为 12.9.6 中定义的 TemplateHead 的 TV。
  2. 令 subRef 为 ? Expression 的 Evaluation。
  3. 令 sub 为 ? GetValue(subRef)。
  4. 令 middle 为 ? ToString(sub)。
  5. 令 tail 为 ? TemplateSpans 的 Evaluation。
  6. 返回 head、middle 和 tail 的字符串连接。
注 1

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

TemplateSpans : TemplateTail
  1. 返回 12.9.6 中定义的 TemplateTail 的 TV。
TemplateSpans : TemplateMiddleList TemplateTail
  1. 令 head 为 ? TemplateMiddleList 的 Evaluation。
  2. 令 tail 为 12.9.6 中定义的 TemplateTail 的 TV。
  3. 返回 head 和 tail 的字符串连接。
TemplateMiddleList : TemplateMiddle Expression
  1. 令 head 为 12.9.6 中定义的 TemplateMiddle 的 TV。
  2. 令 subRef 为 ? Expression 的 Evaluation。
  3. 令 sub 为 ? GetValue(subRef)。
  4. 令 middle 为 ? ToString(sub)。
  5. 返回 head 和 middle 的字符串连接。
注 2

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

TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. 令 rest 为 ? TemplateMiddleList 的 Evaluation。
  2. 令 middle 为 12.9.6 中定义的 TemplateMiddle 的 TV。
  3. 令 subRef 为 ? Expression 的 Evaluation。
  4. 令 sub 为 ? GetValue(subRef)。
  5. 令 last 为 ? ToString(sub)。
  6. 返回 rest、middle 和 last 的字符串连接。
注 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. 返回 ? expr 的 Evaluation。
ParenthesizedExpression : ( Expression )
  1. 返回 ? Expression 的 Evaluation。其类型可能为 Reference。
注

此算法不会对 Expression 的 Evaluation 应用 GetValue。这样做的主要原因是允许将 delete 和 typeof 等运算符应用于括号表达式。

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] ,opt ) 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
  • 如果有任何源文本被此产生式匹配,则为语法错误。
注

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

a?.b
`c`

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

a.b
`c`

后者是有效语句,并且不会应用自动分号插入。

ImportMeta : import . meta

13.3.2 属性访问器

注

属性按名称访问,可以使用点表示法:

或者使用方括号表示法:

点表示法可以通过以下句法转换来解释:

其行为等同于

MemberExpression [ <identifier-name-string> ]

类似地

其行为等同于

CallExpression [ <identifier-name-string> ]

其中 <identifier-name-string> 是 IdentifierName 的 StringValue。

13.3.2.1 Runtime Semantics: Evaluation

MemberExpression : MemberExpression [ Expression ]
  1. 令 baseRef 为 ? MemberExpression 的 Evaluation。
  2. 令 baseValue 为 ? GetValue(baseRef)。
  3. 令 strict 为 IsStrict(this MemberExpression)。
  4. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
MemberExpression : MemberExpression . IdentifierName
  1. 令 baseRef 为 ? MemberExpression 的 Evaluation。
  2. 令 baseValue 为 ? GetValue(baseRef)。
  3. 令 strict 为 IsStrict(this MemberExpression)。
  4. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
MemberExpression : MemberExpression . PrivateIdentifier
  1. 令 baseRef 为 ? MemberExpression 的 Evaluation。
  2. 令 baseValue 为 ? GetValue(baseRef)。
  3. 令 fieldNameString 为 PrivateIdentifier 的 StringValue。
  4. 返回 MakePrivateReference(baseValue, fieldNameString)。
CallExpression : CallExpression [ Expression ]
  1. 令 baseRef 为 ? CallExpression 的 Evaluation。
  2. 令 baseValue 为 ? GetValue(baseRef)。
  3. 令 strict 为 IsStrict(this CallExpression)。
  4. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
CallExpression : CallExpression . IdentifierName
  1. 令 baseRef 为 ? CallExpression 的 Evaluation。
  2. 令 baseValue 为 ? GetValue(baseRef)。
  3. 令 strict 为 IsStrict(this CallExpression)。
  4. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
CallExpression : CallExpression . PrivateIdentifier
  1. 令 baseRef 为 ? CallExpression 的 Evaluation。
  2. 令 baseValue 为 ? GetValue(baseRef)。
  3. 令 fieldNameString 为 PrivateIdentifier 的 StringValue。
  4. 返回 MakePrivateReference(baseValue, fieldNameString)。

13.3.3 EvaluatePropertyAccessWithExpressionKey ( baseValue, expr, strict )

抽象操作 EvaluatePropertyAccessWithExpressionKey,接收参数 baseValue (ECMAScript 语言值)、expr (an Expression Parse Node) 和 strict (Boolean);返回值:(正常完成 (值:Reference 记录) 或 突兀完成)。 调用时执行以下步骤:

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

13.3.4 EvaluatePropertyAccessWithIdentifierKey ( baseValue, identifierName, strict )

抽象操作 EvaluatePropertyAccessWithIdentifierKey,接收参数 baseValue (ECMAScript 语言值)、identifierName (an IdentifierName Parse Node) 和 strict (Boolean);返回值:Reference 记录。 调用时执行以下步骤:

  1. 令 propertyNameString 为 identifierName 的 StringValue。
  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 )

抽象操作 EvaluateNew,接收参数 constructExpr ((a NewExpression Parse Node 或 a MemberExpression Parse Node)) 和 argumentsNode ((empty 或 an Arguments Parse Node));返回值:(正常完成 (值:Object) 或 突兀完成)。 调用时执行以下步骤:

  1. 令 ref 为 ? constructExpr 的 Evaluation。
  2. 令 ctor 为 ? GetValue(ref)。
  3. 如果 argumentsNode 是 empty,则
    1. 令 argList 为新的空 List。
  4. 否则,
    1. 令 argList 为 ? argumentsNode 的 ArgumentListEvaluation。
  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. 令 memberExpr 为 expr 的 MemberExpression。
  3. 令 args 为 expr 的 Arguments。
  4. 令 ref 为 ? memberExpr 的 Evaluation。
  5. 令 func 为 ? GetValue(ref)。
  6. 如果 ref 是 Reference Record、IsPropertyReference(ref) 是 false,且 ref.[[ReferencedName]] 是 "eval",则
    1. 如果 SameValue(func, %eval%) 是 true,则
      1. 令 argList 为 ? args 的 ArgumentListEvaluation。
      2. 如果 argList 没有元素,则返回 undefined。
      3. 令 evalArg 为 argList 的第一个元素。
      4. 如果 IsStrict(this CallExpression) 是 true,则令 strictCaller 为 true;否则令 strictCaller 为 false。
      5. 返回 ? PerformEval(evalArg, strictCaller, true)。
  7. 令 thisCall 为此 CallExpression。
  8. 令 tailCall 为 IsInTailPosition(thisCall)。
  9. 返回 ? EvaluateCall(func, ref, args, tailCall)。

执行步骤 6.a.v 的 CallExpression 求值称为直接 eval。

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

13.3.6.2 EvaluateCall ( func, thisValueRef, argumentListNode, tailPosition )

抽象操作 EvaluateCall,接收参数 func (ECMAScript 语言值)、thisValueRef ((ECMAScript 语言值 或 Reference 记录))、argumentListNode (解析节点) 和 tailPosition (Boolean);返回值:(正常完成 (值:ECMAScript 语言值) 或 突兀完成)。 调用时执行以下步骤:

  1. 如果 thisValueRef 是 Reference Record,则
    1. 如果 IsPropertyReference(thisValueRef) 是 true,则
      1. 令 thisValue 为 GetThisValue(thisValueRef)。
    2. 否则,
      1. 令 refEnv 为 thisValueRef.[[Base]]。
      2. 断言:refEnv 是 Environment Record。
      3. 令 thisValue 为 refEnv.WithBaseObject()。
  2. 否则,
    1. 令 thisValue 为 undefined。
  3. 令 argList 为 ? argumentListNode 的 ArgumentListEvaluation。
  4. 如果 func 不是 Object,则抛出 TypeError 异常。
  5. 如果 IsCallable(func) 是 false,则抛出 TypeError 异常。
  6. 如果 tailPosition 是 true,则执行 PrepareForTailCall()。
  7. 返回 ? Call(func, thisValue, argList)。

13.3.7 super 关键字

13.3.7.1 Runtime Semantics: Evaluation

SuperProperty : super [ Expression ]
  1. 令 envRecord 为 GetThisEnvironment()。
  2. 令 actualThis 为 ? envRecord.GetThisBinding()。
  3. 令 propertyNameRef 为 ? Expression 的 Evaluation。
  4. 令 propertyNameValue 为 ? GetValue(propertyNameRef)。
  5. 令 strict 为 IsStrict(this SuperProperty)。
  6. 注:在大多数情况下,此步骤之后会立即对 propertyNameValue 执行 ToPropertyKey。但是,对于 super[b] = c,直到对 c 求值之后才会执行。
  7. 返回 MakeSuperPropertyReference(actualThis, propertyNameValue, strict)。
SuperProperty : super . IdentifierName
  1. 令 envRecord 为 GetThisEnvironment()。
  2. 令 actualThis 为 ? envRecord.GetThisBinding()。
  3. 令 propertyKey 为 IdentifierName 的 StringValue。
  4. 令 strict 为 IsStrict(this SuperProperty)。
  5. 返回 MakeSuperPropertyReference(actualThis, propertyKey, strict)。
SuperCall : super Arguments
  1. 令 newTarget 为 GetNewTarget()。
  2. 断言:newTarget 是构造函数。
  3. 令 superCtor 为 GetSuperConstructor()。
  4. 令 argList 为 ? Arguments 的 ArgumentListEvaluation。
  5. 如果 IsConstructor(superCtor) 是 false,则抛出 TypeError 异常。
  6. 令 result 为 ? Construct(superCtor, argList, newTarget)。
  7. 令 thisER 为 GetThisEnvironment()。
  8. 断言:thisER 是 Function Environment Record。
  9. 执行 ? BindThisValue(thisER, result)。
  10. 令 funcObj 为 thisER.[[FunctionObject]]。
  11. 断言:funcObj 是 ECMAScript 函数对象。
  12. 执行 ? InitializeInstanceElements(result, funcObj)。
  13. 返回 result。

13.3.7.2 GetSuperConstructor ( )

抽象操作 GetSuperConstructor,接收无参数;返回值:(Object 或 null)。 调用时执行以下步骤:

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

13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict )

抽象操作 MakeSuperPropertyReference,接收参数 actualThis (ECMAScript 语言值)、propertyKey (ECMAScript 语言值) 和 strict (Boolean);返回值:Super Reference 记录。 调用时执行以下步骤:

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

13.3.8 参数列表

注

对参数列表求值会产生值的 List。

13.3.8.1 Runtime Semantics: ArgumentListEvaluation

语法制导操作 ArgumentListEvaluation,接收无参数;返回值:(正常完成 (值:列表 (元素:ECMAScript 语言值)) 或 突兀完成)。 它按以下产生式分别定义:

Arguments : ( )
  1. 返回新的空 List。
ArgumentList : AssignmentExpression
  1. 令 ref 为 ? AssignmentExpression 的 Evaluation。
  2. 令 arg 为 ? GetValue(ref)。
  3. 返回 « arg »。
ArgumentList : ... AssignmentExpression
  1. 令 list 为新的空 List。
  2. 令 spreadRef 为 ? AssignmentExpression 的 Evaluation。
  3. 令 spreadObj 为 ? GetValue(spreadRef)。
  4. 令 iteratorRecord 为 ? GetIterator(spreadObj, sync)。
  5. 重复执行,
    1. 令 next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 next 是 done,则返回 list。
    3. 将 next 追加到 list。
ArgumentList : ArgumentList , AssignmentExpression
  1. 令 precedingArgs 为 ? ArgumentList 的 ArgumentListEvaluation。
  2. 令 ref 为 ? AssignmentExpression 的 Evaluation。
  3. 令 arg 为 ? GetValue(ref)。
  4. 返回 precedingArgs 与 « arg » 的列表连接。
ArgumentList : ArgumentList , ... AssignmentExpression
  1. 令 precedingArgs 为 ? ArgumentList 的 ArgumentListEvaluation。
  2. 令 spreadRef 为 ? AssignmentExpression 的 Evaluation。
  3. 令 iteratorRecord 为 ? GetIterator(? GetValue(spreadRef), sync)。
  4. 重复执行,
    1. 令 next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 next 是 done,则返回 precedingArgs。
    3. 将 next 追加到 precedingArgs。
TemplateLiteral : NoSubstitutionTemplate
  1. 令 templateLiteral 为此 TemplateLiteral。
  2. 令 siteObj 为 GetTemplateObject(templateLiteral)。
  3. 返回 « siteObj »。
TemplateLiteral : SubstitutionTemplate
  1. 令 templateLiteral 为此 TemplateLiteral。
  2. 令 siteObj 为 GetTemplateObject(templateLiteral)。
  3. 令 remaining 为 ? SubstitutionTemplate 的 ArgumentListEvaluation。
  4. 返回 « siteObj » 和 remaining 的列表连接。
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. 令 firstSubRef 为 ? Expression 的 Evaluation。
  2. 令 firstSub 为 ? GetValue(firstSubRef)。
  3. 令 restSub 为 ? TemplateSpans 的 SubstitutionEvaluation。
  4. 断言:restSub 是可能为空的 List。
  5. 返回 « firstSub » 和 restSub 的列表连接。

13.3.9 可选链

注
可选链是一个或多个属性访问和函数调用组成的链,其中第一个以标记 ?. 开始。

13.3.9.1 Runtime Semantics: Evaluation

OptionalExpression : MemberExpression OptionalChain
  1. 令 baseRef 为 ? MemberExpression 的 Evaluation。
  2. 令 baseValue 为 ? GetValue(baseRef)。
  3. 如果 baseValue 是 undefined 或 null,则
    1. 返回 undefined。
  4. 返回 ? 以 baseValue 和 baseRef 为参数对 OptionalChain 执行 ChainEvaluation 的结果。
OptionalExpression : CallExpression OptionalChain
  1. 令 baseRef 为 ? CallExpression 的 Evaluation。
  2. 令 baseValue 为 ? GetValue(baseRef)。
  3. 如果 baseValue 是 undefined 或 null,则
    1. 返回 undefined。
  4. 返回 ? 以 baseValue 和 baseRef 为参数对 OptionalChain 执行 ChainEvaluation 的结果。
OptionalExpression : OptionalExpression OptionalChain
  1. 令 baseRef 为 ? OptionalExpression 的 Evaluation。
  2. 令 baseValue 为 ? GetValue(baseRef)。
  3. 如果 baseValue 是 undefined 或 null,则
    1. 返回 undefined。
  4. 返回 ? 以 baseValue 和 baseRef 为参数对 OptionalChain 执行 ChainEvaluation 的结果。

13.3.9.2 Runtime Semantics: ChainEvaluation

语法制导操作 ChainEvaluation,接收参数 baseValue (ECMAScript 语言值) 和 baseRef ((ECMAScript 语言值 或 Reference 记录));返回值:(正常完成 (值:(ECMAScript 语言值 或 Reference 记录)) 或 突兀完成)。 它按以下产生式分别定义:

OptionalChain : ?. Arguments
  1. 令 thisChain 为此 OptionalChain。
  2. 令 tailCall 为 IsInTailPosition(thisChain)。
  3. 返回 ? EvaluateCall(baseValue, baseRef, Arguments, tailCall)。
OptionalChain : ?. [ Expression ]
  1. 令 strict 为 IsStrict(this OptionalChain)。
  2. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
OptionalChain : ?. IdentifierName
  1. 令 strict 为 IsStrict(this OptionalChain)。
  2. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
OptionalChain : ?. PrivateIdentifier
  1. 令 fieldNameString 为 PrivateIdentifier 的 StringValue。
  2. 返回 MakePrivateReference(baseValue, fieldNameString)。
OptionalChain : OptionalChain Arguments
  1. 令 optionalChain 为 OptionalChain。
  2. 令 newRef 为 ? 以 baseValue 和 baseRef 为参数对 optionalChain 执行 ChainEvaluation 的结果。
  3. 令 newValue 为 ? GetValue(newRef)。
  4. 令 thisChain 为此 OptionalChain。
  5. 令 tailCall 为 IsInTailPosition(thisChain)。
  6. 返回 ? EvaluateCall(newValue, newRef, Arguments, tailCall)。
OptionalChain : OptionalChain [ Expression ]
  1. 令 optionalChain 为 OptionalChain。
  2. 令 newRef 为 ? 以 baseValue 和 baseRef 为参数对 optionalChain 执行 ChainEvaluation 的结果。
  3. 令 newValue 为 ? GetValue(newRef)。
  4. 令 strict 为 IsStrict(this OptionalChain)。
  5. 返回 ? EvaluatePropertyAccessWithExpressionKey(newValue, Expression, strict)。
OptionalChain : OptionalChain . IdentifierName
  1. 令 optionalChain 为 OptionalChain。
  2. 令 newRef 为 ? 以 baseValue 和 baseRef 为参数对 optionalChain 执行 ChainEvaluation 的结果。
  3. 令 newValue 为 ? GetValue(newRef)。
  4. 令 strict 为 IsStrict(this OptionalChain)。
  5. 返回 EvaluatePropertyAccessWithIdentifierKey(newValue, IdentifierName, strict)。
OptionalChain : OptionalChain . PrivateIdentifier
  1. 令 optionalChain 为 OptionalChain。
  2. 令 newRef 为 ? 以 baseValue 和 baseRef 为参数对 optionalChain 执行 ChainEvaluation 的结果。
  3. 令 newValue 为 ? GetValue(newRef)。
  4. 令 fieldNameString 为 PrivateIdentifier 的 StringValue。
  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 ] )

抽象操作 EvaluateImportCall,接收参数 specifierExpr (解析节点)和可选参数 optionsExpr (解析节点);返回值:(正常完成 (值:Promise) 或 突兀完成)。 调用时执行以下步骤:

  1. 令 referrer 为 GetActiveScriptOrModule()。
  2. 如果 referrer 是 null,则将 referrer 设置为当前 Realm Record。
  3. 令 specifierRef 为 ? specifierExpr 的 Evaluation。
  4. 令 specifier 为 ? GetValue(specifierRef)。
  5. 如果存在 optionsExpr,则
    1. 令 optionsRef 为 ? optionsExpr 的 Evaluation。
    2. 令 options 为 ? GetValue(optionsRef)。
  6. 否则,
    1. 令 options 为 undefined。
  7. 令 promiseCapability 为 ! NewPromiseCapability(%Promise%)。
  8. 令 specifierString 为 Completion(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. 令 attrsObj 为 Completion(Get(options, "with"))
    3. IfAbruptRejectPromise(attrsObj, promiseCapability)。
    4. 如果 attrsObj 不是 undefined,则
      1. 如果 attrsObj 不是 Object,则
        1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « 新创建的 TypeError 对象 »)。
        2. 返回 promiseCapability.[[Promise]]。
      2. 令 entries 为 Completion(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. 按 [[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 )

抽象操作 ContinueDynamicImport,接收参数 promiseCapability (PromiseCapability 记录) 和 moduleCompletion ((正常完成 (值:Module 记录) 或 抛出完成));返回值:unused。 它完成最初由 import() 调用启动的动态导入过程,并根据情况兑现或拒绝该调用返回的 promise。 调用时执行以下步骤:

  1. 如果 moduleCompletion 是突然完成,则
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « moduleCompletion.[[Value]] »)。
    2. 返回 unused。
  2. 令 module 为 moduleCompletion.[[Value]]。
  3. 令 loadPromise 为 module.LoadRequestedModules()。
  4. 令 rejectedClosure 为具有参数 (reason) 的新 Abstract Closure,它捕获 promiseCapability,并在被调用时执行以下步骤:
    1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « reason »)。
    2. 返回 NormalCompletion(undefined)。
  5. 令 onRejected 为 CreateBuiltinFunction(rejectedClosure, 1, "", « »)。
  6. 令 linkAndEvaluateClosure 为一个没有参数的新 Abstract Closure,它捕获 module、promiseCapability 和 onRejected,并在被调用时执行以下步骤:
    1. 令 link 为 Completion(module.Link())。
    2. 如果 link 是突然完成,则
      1. 执行 ! Call(promiseCapability.[[Reject]], undefined, « link.[[Value]] »)。
      2. 返回 NormalCompletion(undefined)。
    3. 令 evaluatePromise 为 module.Evaluate()。
    4. 令 fulfilledClosure 为一个没有参数的新 Abstract Closure,它捕获 module 和 promiseCapability,并在被调用时执行以下步骤:
      1. 令 namespace 为 GetModuleNamespace(module)。
      2. 执行 ! Call(promiseCapability.[[Resolve]], undefined, « namespace »)。
      3. 返回 NormalCompletion(undefined)。
    5. 令 onFulfilled 为 CreateBuiltinFunction(fulfilledClosure, 0, "", « »)。
    6. 执行 PerformPromiseThen(evaluatePromise, onFulfilled, onRejected)。
    7. 返回 unused。
  7. 令 linkAndEvaluate 为 CreateBuiltinFunction(linkAndEvaluateClosure, 0, "", « »)。
  8. 执行 PerformPromiseThen(loadPromise, linkAndEvaluate, onRejected)。
  9. 返回 unused。

13.3.11 带标签模板

注

带标签模板是一种函数调用,其调用参数派生自 TemplateLiteral(13.2.8)。实际参数包括模板对象(13.2.8.4)以及对嵌入 TemplateLiteral 中的表达式求值所产生的值。

13.3.11.1 Runtime Semantics: Evaluation

MemberExpression : MemberExpression TemplateLiteral
  1. 令 tagRef 为 ? MemberExpression 的 Evaluation。
  2. 令 tagFunc 为 ? GetValue(tagRef)。
  3. 令 thisCall 为此 MemberExpression。
  4. 令 tailCall 为 IsInTailPosition(thisCall)。
  5. 返回 ? EvaluateCall(tagFunc, tagRef, TemplateLiteral, tailCall)。
CallExpression : CallExpression TemplateLiteral
  1. 令 tagRef 为 ? CallExpression 的 Evaluation。
  2. 令 tagFunc 为 ? GetValue(tagRef)。
  3. 令 thisCall 为此 CallExpression。
  4. 令 tailCall 为 IsInTailPosition(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. 令 module 为 GetActiveScriptOrModule()。
  2. 断言:module 是 Source Text Module Record。
  3. 令 importMeta 为 module.[[ImportMeta]]。
  4. 如果 importMeta 是 empty,则
    1. 将 importMeta 设置为 OrdinaryObjectCreate(null)。
    2. 令 importMetaValues 为 HostGetImportMetaProperties(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 )

宿主定义的抽象操作 HostGetImportMetaProperties,接收参数 moduleRecord (Module 记录);返回值:列表 (元素:记录 (字段:[[Key]] (属性键), [[Value]] (ECMAScript 语言值)))。 它允许宿主为 import.meta 返回的对象提供属性键和值。

HostGetImportMetaProperties 的默认实现返回新的空 List。

13.3.12.1.2 HostFinalizeImportMeta ( importMeta, moduleRecord )

宿主定义的抽象操作 HostFinalizeImportMeta,接收参数 importMeta (Object) 和 moduleRecord (Module 记录);返回值: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 为 ? LeftHandSideExpression 的 Evaluation。
  2. 如果 LeftHandSideExpression 的 AssignmentTargetType 是 web-compat,则抛出 ReferenceError 异常。
  3. 令 oldValue 为 ? ToNumeric(? GetValue(lhs))。
  4. 如果 oldValue 是 Number,则
    1. 令 newValue 为 Number::add(oldValue, 1𝔽)。
  5. 否则,
    1. 断言:oldValue 是 BigInt。
    2. 令 newValue 为 BigInt::add(oldValue, 1ℤ)。
  6. 执行 ? PutValue(lhs, newValue)。
  7. 返回 oldValue。

13.4.3 后缀递减运算符

13.4.3.1 Runtime Semantics: Evaluation

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

13.4.4 前缀递增运算符

13.4.4.1 Runtime Semantics: Evaluation

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

13.4.5 前缀递减运算符

13.4.5.1 Runtime Semantics: Evaluation

UpdateExpression : -- UnaryExpression
  1. 令 expr 为 ? UnaryExpression 的 Evaluation。
  2. 如果 UnaryExpression 的 AssignmentTargetType 是 web-compat,则抛出 ReferenceError 异常。
  3. 令 oldValue 为 ? ToNumeric(? GetValue(expr))。
  4. 如果 oldValue 是 Number,则
    1. 令 newValue 为 Number::subtract(oldValue, 1𝔽)。
  5. 否则,
    1. 断言:oldValue 是 BigInt。
    2. 令 newValue 为 BigInt::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 注

最后一条规则意味着,诸如 delete (((foo))) 之类的表达式会由于递归应用第一条规则而产生提前错误。

13.5.1.2 Runtime Semantics: Evaluation

UnaryExpression : delete UnaryExpression
  1. 令 ref 为 ? UnaryExpression 的 Evaluation。
  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. 如果 deleteStatus 是 false 且 ref.[[Strict]] 是 true,则抛出 TypeError 异常。
    7. 返回 deleteStatus。
  5. 令 base 为 ref.[[Base]]。
  6. 断言:base 是 Environment Record。
  7. 返回 ? base.DeleteBinding(ref.[[ReferencedName]])。
注 1

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

注 2

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

13.5.2 void 运算符

13.5.2.1 Runtime Semantics: Evaluation

UnaryExpression : void UnaryExpression
  1. 令 expr 为 ? UnaryExpression 的 Evaluation。
  2. 执行 ? GetValue(expr)。
  3. 返回 undefined。
注

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

13.5.3 typeof 运算符

13.5.3.1 Runtime Semantics: Evaluation

UnaryExpression : typeof UnaryExpression
  1. 令 value 为 ? UnaryExpression 的 Evaluation。
  2. 如果 value 是 Reference Record,则
    1. 如果 IsUnresolvableReference(value) 是 true,则返回 "undefined"。
  3. 将 value 设置为 ? GetValue(value)。
  4. 如果 value 是 undefined,则返回 "undefined"。
  5. 如果 value 是 null,则返回 "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. Normative Optional
    如果宿主是 Web 浏览器或以其他方式支持 [[IsHTMLDDA]] 内部槽,则
    1. 如果 value 具有 [[IsHTMLDDA]] 内部槽,则返回 "undefined"。
  13. 如果 value 具有 [[Call]] 内部方法,则返回 "function"。
  14. 返回 "object"。

13.5.4 一元 + 运算符

注

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

13.5.4.1 Runtime Semantics: Evaluation

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

13.5.5 一元 - 运算符

注

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

13.5.5.1 Runtime Semantics: Evaluation

UnaryExpression : - UnaryExpression
  1. 令 expr 为 ? UnaryExpression 的 Evaluation。
  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 为 ? UnaryExpression 的 Evaluation。
  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 为 ? UnaryExpression 的 Evaluation。
  2. 令 oldValue 为 ToBoolean(? GetValue(expr))。
  3. 如果 oldValue 是 true,则返回 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 * / % 注
  • * 运算符执行乘法,产生其操作数的乘积。
  • / 运算符执行除法,产生其操作数的商。
  • % 运算符产生其操作数进行隐含除法所得的余数。

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 加法运算符( + )

注

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

13.8.1.1 Runtime Semantics: Evaluation

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

13.8.2 减法运算符( - )

注

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

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 左移运算符( << )

注

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

13.9.1.1 Runtime Semantics: Evaluation

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

13.9.2 有符号右移运算符( >> )

注

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

13.9.2.1 Runtime Semantics: Evaluation

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

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

注

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

13.9.3.1 Runtime Semantics: Evaluation

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

13.10 关系运算符

注 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] 注 2

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

13.10.1 Runtime Semantics: Evaluation

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

13.10.2 InstanceofOperator ( value, target )

抽象操作 InstanceofOperator,接收参数 value (ECMAScript 语言值) 和 target (ECMAScript 语言值);返回值:(正常完成 (值:Boolean) 或 抛出完成)。 它实现用于确定 value 是否为 target 实例的通用算法:首先查询 target 的 %Symbol.hasInstance% 方法;如果该方法不存在,则确定 target 的 "prototype" 属性值是否存在于 value 的原型链中。 调用时执行以下步骤:

  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)。
注

步骤 4 和 5 提供了与先前 ECMAScript 版本的兼容性,这些版本没有使用 %Symbol.hasInstance% 方法定义 instanceof 运算符语义。如果对象既未定义也未继承 %Symbol.hasInstance%,则使用默认的 instanceof 语义。

13.11 相等运算符

注

对相等运算符求值的结果始终为 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 为 ? EqualityExpression 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 令 rightRef 为 ? RelationalExpression 的 Evaluation。
  4. 令 rightValue 为 ? GetValue(rightRef)。
  5. 返回 ? IsLooselyEqual(rightValue, leftValue)。
EqualityExpression : EqualityExpression != RelationalExpression
  1. 令 leftRef 为 ? EqualityExpression 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 令 rightRef 为 ? RelationalExpression 的 Evaluation。
  4. 令 rightValue 为 ? GetValue(rightRef)。
  5. 令 result 为 ? IsLooselyEqual(rightValue, leftValue)。
  6. 如果 result 是 true,则返回 false。
  7. 返回 true。
EqualityExpression : EqualityExpression === RelationalExpression
  1. 令 leftRef 为 ? EqualityExpression 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 令 rightRef 为 ? RelationalExpression 的 Evaluation。
  4. 令 rightValue 为 ? GetValue(rightRef)。
  5. 返回 IsStrictlyEqual(rightValue, leftValue)。
EqualityExpression : EqualityExpression !== RelationalExpression
  1. 令 leftRef 为 ? EqualityExpression 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 令 rightRef 为 ? RelationalExpression 的 Evaluation。
  4. 令 rightValue 为 ? GetValue(rightRef)。
  5. 令 result 为 IsStrictlyEqual(rightValue, leftValue)。
  6. 如果 result 是 true,则返回 false。
  7. 返回 true。
注 1

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

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

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

  • new String("a") == "a" 和 "a" == new String("a") 都是 true。
  • new String("a") == new String("a") 是 false。
注 3

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

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

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

13.13.1 Runtime Semantics: Evaluation

LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. 令 leftRef 为 ? LogicalANDExpression 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 如果 ToBoolean(leftValue) 是 false,则返回 leftValue。
  4. 令 rightRef 为 ? BitwiseORExpression 的 Evaluation。
  5. 返回 ? GetValue(rightRef)。
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. 令 leftRef 为 ? LogicalORExpression 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 如果 ToBoolean(leftValue) 是 true,则返回 leftValue。
  4. 令 rightRef 为 ? LogicalANDExpression 的 Evaluation。
  5. 返回 ? GetValue(rightRef)。
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
  1. 令 leftRef 为 ? CoalesceExpressionHead 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 如果 leftValue 既不是 undefined 也不是 null,则返回 leftValue。
  4. 令 rightRef 为 ? BitwiseORExpression 的 Evaluation。
  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] 注

ECMAScript 中 ConditionalExpression 的文法与 C 和 Java 中的文法略有不同,后两者都允许第二个子表达式为 Expression,但限制第三个表达式必须为 ConditionalExpression。ECMAScript 中采用这种差异,是为了允许条件表达式的任一分支支配赋值表达式,并消除将逗号表达式作为中间表达式这种令人困惑且几乎无用的情况。

13.14.1 Runtime Semantics: Evaluation

ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
  1. 令 leftRef 为 ? ShortCircuitExpression 的 Evaluation。
  2. 令 leftValue 为 ToBoolean(? GetValue(leftRef))。
  3. 如果 leftValue 是 true,则
    1. 令 trueRef 为 ? 第一个 AssignmentExpression 的 Evaluation。
    2. 返回 ? GetValue(trueRef)。
  4. 令 falseRef 为 ? 第二个 AssignmentExpression 的 Evaluation。
  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 为 ? LeftHandSideExpression 的 Evaluation。
    2. 如果 LeftHandSideExpression 的 AssignmentTargetType 是 web-compat,则抛出 ReferenceError 异常。
    3. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 true 且 LeftHandSideExpression 的 IsIdentifierRef 是 true,则
      1. 令 lhs 为 LeftHandSideExpression 的 StringValue。
      2. 令 rightValue 为 ? 以 lhs 为参数对 AssignmentExpression 执行 NamedEvaluation 的结果。
    4. 否则,
      1. 令 rightRef 为 ? AssignmentExpression 的 Evaluation。
      2. 令 rightValue 为 ? GetValue(rightRef)。
    5. 执行 ? PutValue(leftRef, rightValue)。
    6. 返回 rightValue。
  2. 令 assignmentPattern 为 LeftHandSideExpression 所覆盖的 AssignmentPattern。
  3. 令 rightRef 为 ? AssignmentExpression 的 Evaluation。
  4. 令 rightValue 为 ? GetValue(rightRef)。
  5. 执行 ? 以 rightValue 为参数对 assignmentPattern 执行 DestructuringAssignmentEvaluation。
  6. 返回 rightValue。
AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression
  1. 令 leftRef 为 ? LeftHandSideExpression 的 Evaluation。
  2. 如果 LeftHandSideExpression 的 AssignmentTargetType 是 web-compat,则抛出 ReferenceError 异常。
  3. 令 leftValue 为 ? GetValue(leftRef)。
  4. 令 rightRef 为 ? AssignmentExpression 的 Evaluation。
  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 为 ? LeftHandSideExpression 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 如果 ToBoolean(leftValue) 是 false,则返回 leftValue。
  4. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 true 且 LeftHandSideExpression 的 IsIdentifierRef 是 true,则
    1. 令 lhs 为 LeftHandSideExpression 的 StringValue。
    2. 令 rightValue 为 ? 以 lhs 为参数对 AssignmentExpression 执行 NamedEvaluation 的结果。
  5. 否则,
    1. 令 rightRef 为 ? AssignmentExpression 的 Evaluation。
    2. 令 rightValue 为 ? GetValue(rightRef)。
  6. 执行 ? PutValue(leftRef, rightValue)。
  7. 返回 rightValue。
AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
  1. 令 leftRef 为 ? LeftHandSideExpression 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 如果 ToBoolean(leftValue) 是 true,则返回 leftValue。
  4. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 true 且 LeftHandSideExpression 的 IsIdentifierRef 是 true,则
    1. 令 lhs 为 LeftHandSideExpression 的 StringValue。
    2. 令 rightValue 为 ? 以 lhs 为参数对 AssignmentExpression 执行 NamedEvaluation 的结果。
  5. 否则,
    1. 令 rightRef 为 ? AssignmentExpression 的 Evaluation。
    2. 令 rightValue 为 ? GetValue(rightRef)。
  6. 执行 ? PutValue(leftRef, rightValue)。
  7. 返回 rightValue。
AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
  1. 令 leftRef 为 ? LeftHandSideExpression 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 如果 leftValue 既不是 undefined 也不是 null,则返回 leftValue。
  4. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 true 且 LeftHandSideExpression 的 IsIdentifierRef 是 true,则
    1. 令 lhs 为 LeftHandSideExpression 的 StringValue。
    2. 令 rightValue 为 ? 以 lhs 为参数对 AssignmentExpression 执行 NamedEvaluation 的结果。
  5. 否则,
    1. 令 rightRef 为 ? AssignmentExpression 的 Evaluation。
    2. 令 rightValue 为 ? GetValue(rightRef)。
  6. 执行 ? PutValue(leftRef, rightValue)。
  7. 返回 rightValue。
注

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

13.15.3 ApplyStringOrNumericBinaryOperator ( leftValue, opText, rightValue )

抽象操作 ApplyStringOrNumericBinaryOperator,接收参数 leftValue (ECMAScript 语言值)、opText ((**、*、/、%、+、-、<<、>>、>>>、&、^ 或 |)) 和 rightValue (ECMAScript 语言值);返回值:(正常完成 (值:(String、BigInt 或 Number)) 或 抛出完成)。 调用时执行以下步骤:

  1. 如果 opText 是 +,则
    1. 令 leftPrimitive 为 ? ToPrimitive(leftValue)。
    2. 令 rightPrimitive 为 ? ToPrimitive(rightValue)。
    3. 如果 leftPrimitive 是 String 或 rightPrimitive 是 String,则
      1. 令 leftString 为 ? ToString(leftPrimitive)。
      2. 令 rightString 为 ? ToString(rightPrimitive)。
      3. 返回 leftString 和 rightString 的字符串连接。
    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)。
注 1

在步骤 1.a 和 1.b 中调用 ToPrimitive 时未提供 hint。除 Date 外,所有标准对象都会像提供了 number 一样处理缺失的 hint;Date 则像提供了 string 一样处理缺失的 hint。异质对象可以以其他方式处理缺失的 hint。

注 2

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

13.15.4 EvaluateStringOrNumericBinaryExpression ( leftOperand, opText, rightOperand )

抽象操作 EvaluateStringOrNumericBinaryExpression,接收参数 leftOperand (解析节点)、opText ((**、*、/、%、+、-、<<、>>、>>>、&、^ 或 |)) 和 rightOperand (解析节点);返回值:(正常完成 (值:(String、BigInt 或 Number)) 或 突兀完成)。 调用时执行以下步骤:

  1. 令 leftRef 为 ? leftOperand 的 Evaluation。
  2. 令 leftValue 为 ? GetValue(leftRef)。
  3. 令 rightRef 为 ? rightOperand 的 Evaluation。
  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] ,opt } { AssignmentPropertyList[?Yield, ?Await] , AssignmentRestProperty[?Yield, ?Await] } 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

语法制导操作 DestructuringAssignmentEvaluation,接收参数 value (ECMAScript 语言值);返回值:(正常完成 (值:unused) 或 突兀完成)。 它按以下产生式分别定义:

ObjectAssignmentPattern : { }
  1. 执行 ? RequireObjectCoercible(value)。
  2. 返回 unused。
ObjectAssignmentPattern : { AssignmentPropertyList ,opt }
  1. 执行 ? RequireObjectCoercible(value)。
  2. 执行 ? 以 value 为参数对 AssignmentPropertyList 执行 PropertyDestructuringAssignmentEvaluation。
  3. 返回 unused。
ObjectAssignmentPattern : { AssignmentRestProperty }
  1. 执行 ? RequireObjectCoercible(value)。
  2. 令 excludedNames 为新的空 List。
  3. 返回 ? 以 value 和 excludedNames 为参数对 AssignmentRestProperty 执行 RestDestructuringAssignmentEvaluation 的结果。
ObjectAssignmentPattern : { AssignmentPropertyList , AssignmentRestProperty }
  1. 执行 ? RequireObjectCoercible(value)。
  2. 令 excludedNames 为 ? 以 value 为参数对 AssignmentPropertyList 执行 PropertyDestructuringAssignmentEvaluation 的结果。
  3. 返回 ? 以 value 和 excludedNames 为参数对 AssignmentRestProperty 执行 RestDestructuringAssignmentEvaluation 的结果。
ArrayAssignmentPattern : [ ]
  1. 令 iteratorRecord 为 ? GetIterator(value, sync)。
  2. 返回 ? IteratorClose(iteratorRecord, NormalCompletion(unused))。
ArrayAssignmentPattern : [ Elision ]
  1. 令 iteratorRecord 为 ? GetIterator(value, sync)。
  2. 令 result 为 Completion(以 iteratorRecord 为参数对 Elision 执行 IteratorDestructuringAssignmentEvaluation 的结果)。
  3. 如果 iteratorRecord.[[Done]] 是 false,则返回 ? IteratorClose(iteratorRecord, result)。
  4. 返回 result。
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
  1. 令 iteratorRecord 为 ? GetIterator(value, sync)。
  2. 如果存在 Elision,则
    1. 令 status 为 Completion(以 iteratorRecord 为参数对 Elision 执行 IteratorDestructuringAssignmentEvaluation 的结果)。
    2. 如果 status 是突然完成,则
      1. 断言:iteratorRecord.[[Done]] 是 true。
      2. 返回 ? status。
  3. 令 result 为 Completion(以 iteratorRecord 为参数对 AssignmentRestElement 执行 IteratorDestructuringAssignmentEvaluation 的结果)。
  4. 如果 iteratorRecord.[[Done]] 是 false,则返回 ? IteratorClose(iteratorRecord, result)。
  5. 返回 result。
ArrayAssignmentPattern : [ AssignmentElementList ]
  1. 令 iteratorRecord 为 ? GetIterator(value, sync)。
  2. 令 result 为 Completion(以 iteratorRecord 为参数对 AssignmentElementList 执行 IteratorDestructuringAssignmentEvaluation 的结果)。
  3. 如果 iteratorRecord.[[Done]] 是 false,则返回 ? IteratorClose(iteratorRecord, result)。
  4. 返回 result。
ArrayAssignmentPattern : [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
  1. 令 iteratorRecord 为 ? GetIterator(value, sync)。
  2. 令 status 为 Completion(以 iteratorRecord 为参数对 AssignmentElementList 执行 IteratorDestructuringAssignmentEvaluation 的结果)。
  3. 如果 status 是突然完成,则
    1. 如果 iteratorRecord.[[Done]] 是 false,则返回 ? IteratorClose(iteratorRecord, status)。
    2. 返回 ? status。
  4. 如果存在 Elision,则
    1. 将 status 设置为 Completion(以 iteratorRecord 为参数对 Elision 执行 IteratorDestructuringAssignmentEvaluation 的结果)。
    2. 如果 status 是突然完成,则
      1. 断言:iteratorRecord.[[Done]] 是 true。
      2. 返回 ? status。
  5. 如果存在 AssignmentRestElement,则
    1. 将 status 设置为 Completion(以 iteratorRecord 为参数对 AssignmentRestElement 执行 IteratorDestructuringAssignmentEvaluation 的结果)。
  6. 如果 iteratorRecord.[[Done]] 是 false,则返回 ? IteratorClose(iteratorRecord, status)。
  7. 返回 ? status。

13.15.5.3 Runtime Semantics: PropertyDestructuringAssignmentEvaluation

语法制导操作 PropertyDestructuringAssignmentEvaluation,接收参数 value (ECMAScript 语言值);返回值:(正常完成 (值:列表 (元素:属性键)) 或 突兀完成)。 它收集所有被解构属性键的列表。 它按以下产生式分别定义:

AssignmentPropertyList : AssignmentPropertyList , AssignmentProperty
  1. 令 propertyNames 为 ? 以 value 为参数对 AssignmentPropertyList 执行 PropertyDestructuringAssignmentEvaluation 的结果。
  2. 令 nextNames 为 ? 以 value 为参数对 AssignmentProperty 执行 PropertyDestructuringAssignmentEvaluation 的结果。
  3. 返回 propertyNames 和 nextNames 的列表连接。
AssignmentProperty : IdentifierReference Initializeropt
  1. 令 propertyName 为 IdentifierReference 的 StringValue。
  2. 令 leftRef 为 ? ResolveBinding(propertyName)。
  3. 将 value 设置为 ? GetV(value, propertyName)。
  4. 如果存在 Initializer 且 value 是 undefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true,则
      1. 将 value 设置为 ? 以 propertyName 为参数对 Initializer 执行 NamedEvaluation 的结果。
    2. 否则,
      1. 令 defaultValue 为 ? Initializer 的 Evaluation。
      2. 将 value 设置为 ? GetValue(defaultValue)。
  5. 执行 ? PutValue(leftRef, value)。
  6. 返回 « propertyName »。
AssignmentProperty : PropertyName : AssignmentElement
  1. 令 name 为 ? PropertyName 的 Evaluation。
  2. 执行 ? 以 value 和 name 为参数对 AssignmentElement 执行 KeyedDestructuringAssignmentEvaluation。
  3. 返回 « name »。

13.15.5.4 Runtime Semantics: RestDestructuringAssignmentEvaluation

语法制导操作 RestDestructuringAssignmentEvaluation,接收参数 value (ECMAScript 语言值) 和 excludedNames (列表 (元素:属性键));返回值:(正常完成 (值:unused) 或 突兀完成)。 它按以下产生式分别定义:

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

13.15.5.5 Runtime Semantics: IteratorDestructuringAssignmentEvaluation

语法制导操作 IteratorDestructuringAssignmentEvaluation,接收参数 iteratorRecord (Iterator 记录);返回值:(正常完成 (值:unused) 或 突兀完成)。 它按以下产生式分别定义:

AssignmentElementList : AssignmentElisionElement
  1. 返回 ? 以 iteratorRecord 为参数对 AssignmentElisionElement 执行 IteratorDestructuringAssignmentEvaluation 的结果。
AssignmentElementList : AssignmentElementList , AssignmentElisionElement
  1. 执行 ? 以 iteratorRecord 为参数对 AssignmentElementList 执行 IteratorDestructuringAssignmentEvaluation。
  2. 返回 ? 以 iteratorRecord 为参数对 AssignmentElisionElement 执行 IteratorDestructuringAssignmentEvaluation 的结果。
AssignmentElisionElement : AssignmentElement
  1. 返回 ? 以 iteratorRecord 为参数对 AssignmentElement 执行 IteratorDestructuringAssignmentEvaluation 的结果。
AssignmentElisionElement : Elision AssignmentElement
  1. 执行 ? 以 iteratorRecord 为参数对 Elision 执行 IteratorDestructuringAssignmentEvaluation。
  2. 返回 ? 以 iteratorRecord 为参数对 AssignmentElement 执行 IteratorDestructuringAssignmentEvaluation 的结果。
Elision : ,
  1. 如果 iteratorRecord.[[Done]] 是 false,则
    1. 执行 ? IteratorStep(iteratorRecord)。
  2. 返回 unused。
Elision : Elision ,
  1. 执行 ? 以 iteratorRecord 为参数对 Elision 执行 IteratorDestructuringAssignmentEvaluation。
  2. 如果 iteratorRecord.[[Done]] 是 false,则
    1. 执行 ? IteratorStep(iteratorRecord)。
  3. 返回 unused。
AssignmentElement : DestructuringAssignmentTarget Initializeropt
  1. 如果 DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. 令 leftRef 为 ? DestructuringAssignmentTarget 的 Evaluation。
  2. 令 value 为 undefined。
  3. 如果 iteratorRecord.[[Done]] 是 false,则
    1. 令 next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 next 不是 done,则
      1. 将 value 设置为 next。
  4. 如果存在 Initializer 且 value 是 undefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true 且 DestructuringAssignmentTarget 的 IsIdentifierRef 是 true,则
      1. 令 target 为 DestructuringAssignmentTarget 的 StringValue。
      2. 将 value 设置为 ? 以 target 为参数对 Initializer 执行 NamedEvaluation 的结果。
    2. 否则,
      1. 令 defaultValue 为 ? Initializer 的 Evaluation。
      2. 将 value 设置为 ? GetValue(defaultValue)。
  5. 如果 DestructuringAssignmentTarget 是 ObjectLiteral 或 ArrayLiteral,则
    1. 令 nestedAssignmentPattern 为 DestructuringAssignmentTarget 所覆盖的 AssignmentPattern。
    2. 返回 ? 以 value 为参数对 nestedAssignmentPattern 执行 DestructuringAssignmentEvaluation 的结果。
  6. 返回 ? PutValue(leftRef, value)。
注

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

AssignmentRestElement : ... DestructuringAssignmentTarget
  1. 如果 DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. 令 leftRef 为 ? DestructuringAssignmentTarget 的 Evaluation。
  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 为参数对 nestedAssignmentPattern 执行 DestructuringAssignmentEvaluation 的结果。

13.15.5.6 Runtime Semantics: KeyedDestructuringAssignmentEvaluation

语法制导操作 KeyedDestructuringAssignmentEvaluation,接收参数 value (ECMAScript 语言值) 和 propertyName (属性键);返回值:(正常完成 (值:unused) 或 突兀完成)。 它按以下产生式分别定义:

AssignmentElement : DestructuringAssignmentTarget Initializeropt
  1. 如果 DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral,则
    1. 令 leftRef 为 ? DestructuringAssignmentTarget 的 Evaluation。
  2. 将 value 设置为 ? GetV(value, propertyName)。
  3. 如果存在 Initializer 且 value 是 undefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true 且 DestructuringAssignmentTarget 的 IsIdentifierRef 是 true,则
      1. 令 target 为 DestructuringAssignmentTarget 的 StringValue。
      2. 令 rhsValue 为 ? 以 target 为参数对 Initializer 执行 NamedEvaluation 的结果。
    2. 否则,
      1. 令 defaultValue 为 ? Initializer 的 Evaluation。
      2. 令 rhsValue 为 ? GetValue(defaultValue)。
  4. 否则,
    1. 令 rhsValue 为 value。
  5. 如果 DestructuringAssignmentTarget 是 ObjectLiteral 或 ArrayLiteral,则
    1. 令 assignmentPattern 为 DestructuringAssignmentTarget 所覆盖的 AssignmentPattern。
    2. 返回 ? 以 rhsValue 为参数对 assignmentPattern 执行 DestructuringAssignmentEvaluation 的结果。
  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 为 ? Expression 的 Evaluation。
  2. 执行 ? GetValue(leftRef)。
  3. 令 rightRef 为 ? AssignmentExpression 的 Evaluation。
  4. 返回 ? GetValue(rightRef)。
注

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