页面模式偏好

14 ECMAScript 语言:语句和声明

语法

Statement[Yield, Await, Return] : BlockStatement[?Yield, ?Await, ?Return] VariableStatement[?Yield, ?Await] EmptyStatement ExpressionStatement[?Yield, ?Await] IfStatement[?Yield, ?Await, ?Return] BreakableStatement[?Yield, ?Await, ?Return] ContinueStatement[?Yield, ?Await] BreakStatement[?Yield, ?Await] [+Return] ReturnStatement[?Yield, ?Await] WithStatement[?Yield, ?Await, ?Return] LabelledStatement[?Yield, ?Await, ?Return] ThrowStatement[?Yield, ?Await] TryStatement[?Yield, ?Await, ?Return] DebuggerStatement Declaration[Yield, Await] : HoistableDeclaration[?Yield, ?Await, ~Default] ClassDeclaration[?Yield, ?Await, ~Default] LexicalDeclaration[+In, ?Yield, ?Await] HoistableDeclaration[Yield, Await, Default] : FunctionDeclaration[?Yield, ?Await, ?Default] GeneratorDeclaration[?Yield, ?Await, ?Default] AsyncFunctionDeclaration[?Yield, ?Await, ?Default] AsyncGeneratorDeclaration[?Yield, ?Await, ?Default] BreakableStatement[Yield, Await, Return] : IterationStatement[?Yield, ?Await, ?Return] SwitchStatement[?Yield, ?Await, ?Return]

14.1 语句语义

14.1.1 Runtime Semantics: Evaluation

HoistableDeclaration : GeneratorDeclaration AsyncFunctionDeclaration AsyncGeneratorDeclaration
  1. 返回 empty。
HoistableDeclaration : FunctionDeclaration
  1. 返回 ? FunctionDeclaration 的 Evaluation。
BreakableStatement : IterationStatement SwitchStatement
  1. 令 newLabelSet 为新的空 List。
  2. 返回 ? 以 newLabelSet 为参数对当前 BreakableStatement 执行 LabelledEvaluation 的结果。

14.2 块

语法

BlockStatement[Yield, Await, Return] : Block[?Yield, ?Await, ?Return] Block[Yield, Await, Return] : { StatementList[?Yield, ?Await, ?Return]opt } StatementList[Yield, Await, Return] : StatementListItem[?Yield, ?Await, ?Return] StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return] StatementListItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] Declaration[?Yield, ?Await]

14.2.1 Static Semantics: 提前错误

Block : { StatementList }

14.2.2 Runtime Semantics: Evaluation

Block : { }
  1. 返回 empty。
Block : { StatementList }
  1. 令 oldEnv 为正在运行的执行上下文的 LexicalEnvironment。
  2. 令 blockEnv 为 NewDeclarativeEnvironment(oldEnv)。
  3. 执行 BlockDeclarationInstantiation(StatementList, blockEnv)。
  4. 将正在运行的执行上下文的 LexicalEnvironment 设置为 blockEnv。
  5. 令 blockValue 为 Completion(StatementList 的 Evaluation)。
  6. 将 blockValue 设置为 Completion(DisposeResources(blockEnv.[[DisposableResourceStack]], blockValue))。
  7. 将正在运行的执行上下文的 LexicalEnvironment 设置为 oldEnv。
  8. 返回 ? blockValue。
注 1

无论控制如何离开 Block,LexicalEnvironment 始终会恢复为其先前状态。

StatementList : StatementList StatementListItem
  1. 令 sl 为 ? StatementList 的 Evaluation。
  2. 令 s 为 Completion(StatementListItem 的 Evaluation)。
  3. 返回 ? UpdateEmpty(s, sl)。
注 2

StatementList 的值是 StatementList 中最后一个产生值的项的值。例如,以下对 eval 函数的调用都返回值 1:

eval("1;;;;;")
eval("1;{}")
eval("1;var a;")

14.2.3 BlockDeclarationInstantiation ( code, envRecord )

抽象操作 BlockDeclarationInstantiation,接收参数 code (解析节点) 和 envRecord (Declarative Environment 记录);返回值:unused。 code 是与块主体对应的 Parse Node。envRecord 是将在其中创建绑定的 Environment Record。

注

当对 Block 或 CaseBlock 求值时,会创建一个新的 Declarative Environment Record,并在该 Environment Record 中实例化块内声明的每个块作用域变量、常量、函数或类的绑定。

调用时,它执行以下步骤:

  1. 令 decls 为 code 的 LexicallyScopedDeclarations。
  2. 令 privateEnv 为正在运行的执行上下文的 PrivateEnvironment。
  3. 对 decls 的每个元素 decl,执行
    1. 对 decl 的 BoundNames 的每个元素 name,执行
      1. 如果 decl 的 IsConstantDeclaration 是 true,则
        1. 执行 ! envRecord.CreateImmutableBinding(name, true)。
      2. 否则,
        1. Normative Optional
          如果宿主是 Web 浏览器或以其他方式支持 块级函数声明的 Web 遗留兼容性语义,则
          1. 如果 ! envRecord.HasBinding(name) 是 false,则
            1. 执行 ! envRecord.CreateMutableBinding(name, false)。
        2. 否则,
          1. 执行 ! envRecord.CreateMutableBinding(name, false)。
    2. 如果 decl 是 FunctionDeclaration、GeneratorDeclaration、AsyncFunctionDeclaration 或 AsyncGeneratorDeclaration 之一,则
      1. 令 funcName 为 decl 的 BoundNames 的唯一元素。
      2. 令 funcObj 为以 envRecord 和 privateEnv 为参数对 decl 执行 InstantiateFunctionObject 的结果。
      3. Normative Optional
        如果宿主是 Web 浏览器或以其他方式支持 块级函数声明的 Web 遗留兼容性语义,则
        1. 如果 envRecord 中 funcName 的绑定是尚未初始化的绑定,则
          1. 执行 ! envRecord.InitializeBinding(funcName, funcObj)。
        2. 否则,
          1. 断言:decl 是 FunctionDeclaration。
          2. 执行 ! envRecord.SetMutableBinding(funcName, funcObj, false)。
      4. 否则,
        1. 执行 ! envRecord.InitializeBinding(funcName, funcObj)。
  4. 返回 unused。

14.3 声明和变量语句

14.3.1 let、const、using 和 await using 声明

注

let、const、using 和 await using 声明定义作用域限定于正在运行的执行上下文的 LexicalEnvironment 的变量。变量在其所包含的 Environment Record 被实例化时创建,但在变量的 LexicalBinding 被求值之前,不得以任何方式访问变量。当对 LexicalBinding 求值时,由具有 Initializer 的 LexicalBinding 定义的变量会被赋予其 Initializer 的 AssignmentExpression 的值,而不是在创建变量时赋值。如果 let 声明中的 LexicalBinding 没有 Initializer,则在对 LexicalBinding 求值时,该变量被赋予值 undefined。

语法

LexicalDeclaration[In, Yield, Await] : LetOrConst BindingList[?In, ?Yield, ?Await, +Pattern] ; UsingDeclaration[?In, ?Yield, ?Await] [+Await] AwaitUsingDeclaration[?In, ?Yield] LetOrConst : let const UsingDeclaration[In, Yield, Await] : using [no LineTerminator here] BindingList[?In, ?Yield, ?Await, ~Pattern] ; AwaitUsingDeclaration[In, Yield] : CoverAwaitExpressionAndAwaitUsingDeclarationHead[?Yield] [no LineTerminator here] BindingList[?In, ?Yield, +Await, ~Pattern] ; BindingList[In, Yield, Await, Pattern] : LexicalBinding[?In, ?Yield, ?Await, ?Pattern] BindingList[?In, ?Yield, ?Await, ?Pattern] , LexicalBinding[?In, ?Yield, ?Await, ?Pattern] LexicalBinding[In, Yield, Await, Pattern] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt [+Pattern] BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

补充语法

当处理产生式
AwaitUsingDeclaration : CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList ;
的实例时,使用以下文法进一步细化对 CoverAwaitExpressionAndAwaitUsingDeclarationHead 的解释:

AwaitUsingDeclarationHead : await [no LineTerminator here] using

14.3.1.1 Static Semantics: 提前错误

LexicalDeclaration : LetOrConst BindingList ; UsingDeclaration : using BindingList ; AwaitUsingDeclaration : CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList ; LexicalBinding : BindingIdentifier Initializeropt

14.3.1.2 Runtime Semantics: Evaluation

LexicalDeclaration : LetOrConst BindingList ;
  1. 执行 ? 以 normal 为参数对 BindingList 执行 BindingEvaluation。
  2. 返回 empty。
UsingDeclaration : using BindingList ;
  1. 执行 ? 以 sync-dispose 为参数对 BindingList 执行 BindingEvaluation。
  2. 返回 empty。
AwaitUsingDeclaration : CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList ;
  1. 执行 ? 以 async-dispose 为参数对 BindingList 执行 BindingEvaluation。
  2. 返回 empty。

14.3.1.3 Runtime Semantics: BindingEvaluation

语法制导操作 BindingEvaluation,接收参数 kind ((normal、sync-dispose 或 async-dispose));返回值:(正常完成 (值:unused) 或 突兀完成)。 它按以下产生式分别定义:

BindingList : BindingList , LexicalBinding
  1. 执行 ? 以 kind 为参数对派生的 BindingList 执行 BindingEvaluation。
  2. 返回 ? 以 kind 为参数对 LexicalBinding 执行 BindingEvaluation 的结果。
LexicalBinding : BindingIdentifier
  1. 断言:kind 是 normal。
  2. 令 lhs 为 ! ResolveBinding(BindingIdentifier 的 StringValue)。
  3. 执行 ! InitializeReferencedBinding(lhs, undefined)。
  4. 返回 unused。
注

静态语义规则确保这种形式的 LexicalBinding 永远不会出现在 const、using 或 await using 声明中。

LexicalBinding : BindingIdentifier Initializer
  1. 令 name 为 BindingIdentifier 的 StringValue。
  2. 令 lhs 为 ! ResolveBinding(name)。
  3. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true,则
    1. 令 value 为 ? 以 name 为参数对 Initializer 执行 NamedEvaluation 的结果。
  4. 否则,
    1. 令 rhs 为 ? Initializer 的 Evaluation。
    2. 令 value 为 ? GetValue(rhs)。
  5. 如果 kind 不是 normal,则
    1. 断言:IsUnresolvableReference(lhs) 是 false。
    2. 令 base 为 lhs.[[Base]]。
    3. 断言:base 是 Declarative Environment Record。
    4. 执行 ? AddDisposableResource(base.[[DisposableResourceStack]], value, kind)。
  6. 执行 ? InitializeReferencedBinding(lhs, value)。
  7. 返回 unused。
LexicalBinding : BindingPattern Initializer
  1. 断言:kind 是 normal。
  2. 令 rhs 为 ? Initializer 的 Evaluation。
  3. 令 value 为 ? GetValue(rhs)。
  4. 令 envRecord 为正在运行的执行上下文的 LexicalEnvironment。
  5. 返回 ? 以 value 和 envRecord 为参数对 BindingPattern 执行 BindingInitialization 的结果。

14.3.2 变量语句

注

var 语句声明作用域限定于正在运行的执行上下文的 VariableEnvironment 的变量。var 变量在其所包含的 Environment Record 被实例化时创建,并在创建时初始化为 undefined。在任何 VariableEnvironment 的作用域内,同一个 BindingIdentifier 可以出现在多个 VariableDeclaration 中,但这些声明合起来只定义一个变量。当执行 VariableDeclaration 时,由具有 Initializer 的 VariableDeclaration 定义的变量会被赋予其 Initializer 的 AssignmentExpression 的值,而不是在创建变量时赋值。

语法

VariableStatement[Yield, Await] : var VariableDeclarationList[+In, ?Yield, ?Await] ; VariableDeclarationList[In, Yield, Await] : VariableDeclaration[?In, ?Yield, ?Await] VariableDeclarationList[?In, ?Yield, ?Await] , VariableDeclaration[?In, ?Yield, ?Await] VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.2.1 Runtime Semantics: Evaluation

VariableStatement : var VariableDeclarationList ;
  1. 执行 ? VariableDeclarationList 的 Evaluation。
  2. 返回 empty。
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. 执行 ? VariableDeclarationList 的 Evaluation。
  2. 返回 ? VariableDeclaration 的 Evaluation。
VariableDeclaration : BindingIdentifier
  1. 返回 empty。
VariableDeclaration : BindingIdentifier Initializer
  1. 令 name 为 BindingIdentifier 的 StringValue。
  2. 令 lhs 为 ? ResolveBinding(name)。
  3. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true,则
    1. 令 value 为 ? 以 name 为参数对 Initializer 执行 NamedEvaluation 的结果。
  4. 否则,
    1. 令 rhs 为 ? Initializer 的 Evaluation。
    2. 令 value 为 ? GetValue(rhs)。
  5. 执行 ? PutValue(lhs, value)。
  6. 返回 empty。
注

如果 VariableDeclaration 嵌套在 with 语句中,并且 VariableDeclaration 中的 BindingIdentifier 与该 with 语句的 Object Environment Record 的绑定对象的某个属性名称相同,则步骤 5 会将 value 赋给该属性,而不是赋给 Identifier 的 VariableEnvironment 绑定。

VariableDeclaration : BindingPattern Initializer
  1. 令 rhs 为 ? Initializer 的 Evaluation。
  2. 令 rightValue 为 ? GetValue(rhs)。
  3. 返回 ? 以 rightValue 和 undefined 为参数对 BindingPattern 执行 BindingInitialization 的结果。

14.3.3 解构绑定模式

语法

BindingPattern[Yield, Await] : ObjectBindingPattern[?Yield, ?Await] ArrayBindingPattern[?Yield, ?Await] ObjectBindingPattern[Yield, Await] : { } { BindingRestProperty[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] ,opt } { BindingPropertyList[?Yield, ?Await] , BindingRestProperty[?Yield, ?Await] } ArrayBindingPattern[Yield, Await] : [ Elisionopt BindingRestElement[?Yield, ?Await]opt ] [ BindingElementList[?Yield, ?Await] ] [ BindingElementList[?Yield, ?Await] , Elisionopt BindingRestElement[?Yield, ?Await]opt ] BindingRestProperty[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] BindingPropertyList[Yield, Await] : BindingProperty[?Yield, ?Await] BindingPropertyList[?Yield, ?Await] , BindingProperty[?Yield, ?Await] BindingElementList[Yield, Await] : BindingElisionElement[?Yield, ?Await] BindingElementList[?Yield, ?Await] , BindingElisionElement[?Yield, ?Await] BindingElisionElement[Yield, Await] : Elisionopt BindingElement[?Yield, ?Await] BindingProperty[Yield, Await] : SingleNameBinding[?Yield, ?Await] PropertyName[?Yield, ?Await] : BindingElement[?Yield, ?Await] BindingElement[Yield, Await] : SingleNameBinding[?Yield, ?Await] BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt SingleNameBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt BindingRestElement[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] ... BindingPattern[?Yield, ?Await]

14.3.3.1 Runtime Semantics: PropertyBindingInitialization

语法制导操作 PropertyBindingInitialization,接收参数 value (ECMAScript 语言值) 和 envRecord ((Environment 记录 或 undefined));返回值:(正常完成 (值:列表 (元素:属性键)) 或 突兀完成)。 它收集所有已绑定属性名称的列表。 它按以下产生式分别定义:

BindingPropertyList : BindingPropertyList , BindingProperty
  1. 令 boundNames 为 ? 以 value 和 envRecord 为参数对 BindingPropertyList 执行 PropertyBindingInitialization 的结果。
  2. 令 nextNames 为 ? 以 value 和 envRecord 为参数对 BindingProperty 执行 PropertyBindingInitialization 的结果。
  3. 返回 boundNames 和 nextNames 的列表连接。
BindingProperty : SingleNameBinding
  1. 令 name 为 SingleNameBinding 的 BoundNames 的唯一元素。
  2. 执行 ? 以 value、envRecord 和 name 为参数对 SingleNameBinding 执行 KeyedBindingInitialization。
  3. 返回 « name »。
BindingProperty : PropertyName : BindingElement
  1. 令 propertyKey 为 ? PropertyName 的 Evaluation。
  2. 执行 ? 以 value、envRecord 和 propertyKey 为参数对 BindingElement 执行 KeyedBindingInitialization。
  3. 返回 « propertyKey »。

14.3.3.2 Runtime Semantics: RestBindingInitialization

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

BindingRestProperty : ... BindingIdentifier
  1. 令 lhs 为 ? ResolveBinding(BindingIdentifier 的 StringValue, envRecord)。
  2. 令 restObj 为 OrdinaryObjectCreate(%Object.prototype%)。
  3. 执行 ? CopyDataProperties(restObj, value, excludedNames)。
  4. 如果 envRecord 是 undefined,则返回 ? PutValue(lhs, restObj)。
  5. 返回 ? InitializeReferencedBinding(lhs, restObj)。

14.3.3.3 Runtime Semantics: KeyedBindingInitialization

语法制导操作 KeyedBindingInitialization,接收参数 value (ECMAScript 语言值)、envRecord ((Environment 记录 或 undefined)) 和 propertyName (属性键);返回值:(正常完成 (值:unused) 或 突兀完成)。

注

当为 envRecord 传入 undefined 时,表示应使用 PutValue 操作来赋予初始化值。这适用于非严格函数的形式参数列表。在这种情况下,形式参数绑定会被预先初始化,以处理多个参数具有相同名称的可能性。

它按以下产生式分别定义:

BindingElement : BindingPattern Initializeropt
  1. 将 value 设置为 ? GetV(value, propertyName)。
  2. 如果存在 Initializer 且 value 是 undefined,则
    1. 令 defaultValue 为 ? Initializer 的 Evaluation。
    2. 将 value 设置为 ? GetValue(defaultValue)。
  3. 返回 ? 以 value 和 envRecord 为参数对 BindingPattern 执行 BindingInitialization 的结果。
SingleNameBinding : BindingIdentifier Initializeropt
  1. 令 name 为 BindingIdentifier 的 StringValue。
  2. 令 lhs 为 ? ResolveBinding(name, envRecord)。
  3. 将 value 设置为 ? GetV(value, propertyName)。
  4. 如果存在 Initializer 且 value 是 undefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true,则
      1. 将 value 设置为 ? 以 name 为参数对 Initializer 执行 NamedEvaluation 的结果。
    2. 否则,
      1. 令 defaultValue 为 ? Initializer 的 Evaluation。
      2. 将 value 设置为 ? GetValue(defaultValue)。
  5. 如果 envRecord 是 undefined,则返回 ? PutValue(lhs, value)。
  6. 返回 ? InitializeReferencedBinding(lhs, value)。

14.4 空语句

语法

EmptyStatement : ;

14.4.1 Runtime Semantics: Evaluation

EmptyStatement : ;
  1. 返回 empty。

14.5 表达式语句

语法

ExpressionStatement[Yield, Await] : [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }] Expression[+In, ?Yield, ?Await] ; 注

ExpressionStatement 不能以 U+007B (LEFT CURLY BRACKET) 开头,因为这可能使其与 Block 产生歧义。ExpressionStatement 不能以 function 或 class 关键字开头,因为这会使其与 FunctionDeclaration、GeneratorDeclaration 或 ClassDeclaration 产生歧义。ExpressionStatement 不能以 async function 开头,因为这会使其与 AsyncFunctionDeclaration 或 AsyncGeneratorDeclaration 产生歧义。ExpressionStatement 不能以两个标记组成的序列 let [ 开头,因为这会使其与第一个 LexicalBinding 为 ArrayBindingPattern 的 let LexicalDeclaration 产生歧义。

14.5.1 Runtime Semantics: Evaluation

ExpressionStatement : Expression ;
  1. 令 exprRef 为 ? Expression 的 Evaluation。
  2. 返回 ? GetValue(exprRef)。

14.6 if 语句

语法

IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [lookahead ≠ else] 注
前瞻限制 [lookahead ≠ else] 以通常方式解决经典的“悬空 else”问题。也就是说,当要关联的 if 在其他方面存在歧义时,else 会与候选 if 中最近(最内层)的那个关联

14.6.1 Static Semantics: 提前错误

IfStatement : if ( Expression ) Statement else Statement IfStatement : if ( Expression ) Statement 注

只有在实现了 B.3.1 中规定的扩展时,才需要应用此规则。

14.6.2 Runtime Semantics: Evaluation

IfStatement : if ( Expression ) Statement else Statement
  1. 令 exprRef 为 ? Expression 的 Evaluation。
  2. 令 exprValue 为 ToBoolean(? GetValue(exprRef))。
  3. 如果 exprValue 是 true,则
    1. 令 stmtCompletion 为 Completion(第一个 Statement 的 Evaluation)。
  4. 否则,
    1. 令 stmtCompletion 为 Completion(第二个 Statement 的 Evaluation)。
  5. 返回 ? UpdateEmpty(stmtCompletion, undefined)。
IfStatement : if ( Expression ) Statement
  1. 令 exprRef 为 ? Expression 的 Evaluation。
  2. 令 exprValue 为 ToBoolean(? GetValue(exprRef))。
  3. 如果 exprValue 是 false,则返回 undefined。
  4. 令 stmtCompletion 为 Completion(Statement 的 Evaluation)。
  5. 返回 ? UpdateEmpty(stmtCompletion, undefined)。

14.7 迭代语句

语法

IterationStatement[Yield, Await, Return] : DoWhileStatement[?Yield, ?Await, ?Return] WhileStatement[?Yield, ?Await, ?Return] ForStatement[?Yield, ?Await, ?Return] ForInOfStatement[?Yield, ?Await, ?Return]

14.7.1 语义

14.7.1.1 LoopContinues ( completion, labelSet )

抽象操作 LoopContinues,接收参数 completion (完成记录) 和 labelSet (列表 (元素:String));返回值:Boolean。 调用时执行以下步骤:

  1. 如果 completion 是正常完成,则返回 true。
  2. 如果 completion 不是 continue 完成,则返回 false。
  3. 如果 completion.[[Target]] 是 empty,则返回 true。
  4. 如果 labelSet 包含 completion.[[Target]],则返回 true。
  5. 返回 false。
注

在 IterationStatement 的 Statement 部分中,可以使用 ContinueStatement 开始新的迭代。

14.7.1.2 Runtime Semantics: LoopEvaluation

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

IterationStatement : DoWhileStatement
  1. 返回 ? 以 labelSet 为参数对 DoWhileStatement 执行 DoWhileLoopEvaluation 的结果。
IterationStatement : WhileStatement
  1. 返回 ? 以 labelSet 为参数对 WhileStatement 执行 WhileLoopEvaluation 的结果。
IterationStatement : ForStatement
  1. 返回 ? 以 labelSet 为参数对 ForStatement 执行 ForLoopEvaluation 的结果。
IterationStatement : ForInOfStatement
  1. 返回 ? 以 labelSet 为参数对 ForInOfStatement 执行 ForInOfLoopEvaluation 的结果。

14.7.2 do-while 语句

语法

DoWhileStatement[Yield, Await, Return] : do Statement[?Yield, ?Await, ?Return] while ( Expression[+In, ?Yield, ?Await] ) ;

14.7.2.1 Static Semantics: 提前错误

DoWhileStatement : do Statement while ( Expression ) ; 注

只有在实现了 B.3.1 中规定的扩展时,才需要应用此规则。

14.7.2.2 Runtime Semantics: DoWhileLoopEvaluation

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

DoWhileStatement : do Statement while ( Expression ) ;
  1. 令 iterationResult 为 undefined。
  2. 重复执行,
    1. 令 stmtResult 为 Completion(Statement 的 Evaluation)。
    2. 如果 LoopContinues(stmtResult, labelSet) 是 false,则返回 ? UpdateEmpty(stmtResult, iterationResult)。
    3. 如果 stmtResult.[[Value]] 不是 empty,则将 iterationResult 设置为 stmtResult.[[Value]]。
    4. 令 exprRef 为 ? Expression 的 Evaluation。
    5. 令 exprValue 为 ? GetValue(exprRef)。
    6. 如果 ToBoolean(exprValue) 是 false,则返回 iterationResult。

14.7.3 while 语句

语法

WhileStatement[Yield, Await, Return] : while ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]

14.7.3.1 Static Semantics: 提前错误

WhileStatement : while ( Expression ) Statement 注

只有在实现了 B.3.1 中规定的扩展时,才需要应用此规则。

14.7.3.2 Runtime Semantics: WhileLoopEvaluation

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

WhileStatement : while ( Expression ) Statement
  1. 令 iterationResult 为 undefined。
  2. 重复执行,
    1. 令 exprRef 为 ? Expression 的 Evaluation。
    2. 令 exprValue 为 ? GetValue(exprRef)。
    3. 如果 ToBoolean(exprValue) 是 false,则返回 iterationResult。
    4. 令 stmtResult 为 Completion(Statement 的 Evaluation)。
    5. 如果 LoopContinues(stmtResult, labelSet) 是 false,则返回 ? UpdateEmpty(stmtResult, iterationResult)。
    6. 如果 stmtResult.[[Value]] 不是 empty,则将 iterationResult 设置为 stmtResult.[[Value]]。

14.7.4 for 语句

语法

ForStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] Expression[~In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( var VariableDeclarationList[~In, ?Yield, ?Await] ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( LexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return]

14.7.4.1 Static Semantics: 提前错误

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement 注

只有在实现了 B.3.1 中规定的扩展时,才需要应用此规则。

ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

14.7.4.2 Runtime Semantics: ForLoopEvaluation

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

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. 如果存在第一个 Expression,则
    1. 令 exprRef 为 ? 第一个 Expression 的 Evaluation。
    2. 执行 ? GetValue(exprRef)。
  2. 如果存在第二个 Expression,则令 test 为第二个 Expression;否则令 test 为 empty。
  3. 如果存在第三个 Expression,则令 increment 为第三个 Expression;否则令 increment 为 empty。
  4. 返回 ? ForBodyEvaluation(test, increment, Statement, « », labelSet)。
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. 执行 ? VariableDeclarationList 的 Evaluation。
  2. 如果存在第一个 Expression,则令 test 为第一个 Expression;否则令 test 为 empty。
  3. 如果存在第二个 Expression,则令 increment 为第二个 Expression;否则令 increment 为 empty。
  4. 返回 ? ForBodyEvaluation(test, increment, Statement, « », labelSet)。
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 令 oldEnv 为正在运行的执行上下文的 LexicalEnvironment。
  2. 令 loopEnv 为 NewDeclarativeEnvironment(oldEnv)。
  3. 令 isConst 为 LexicalDeclaration 的 IsConstantDeclaration。
  4. 令 boundNames 为 LexicalDeclaration 的 BoundNames。
  5. 对 boundNames 的每个元素 name,执行
    1. 如果 isConst 是 true,则
      1. 执行 ! loopEnv.CreateImmutableBinding(name, true)。
    2. 否则,
      1. 执行 ! loopEnv.CreateMutableBinding(name, false)。
  6. 将正在运行的执行上下文的 LexicalEnvironment 设置为 loopEnv。
  7. 令 forDecl 为 Completion(LexicalDeclaration 的 Evaluation)。
  8. 如果 forDecl 是突然完成,则
    1. 将 forDecl 设置为 Completion(DisposeResources(loopEnv.[[DisposableResourceStack]], forDecl))。
    2. 断言:forDecl 是突然完成。
    3. 将正在运行的执行上下文的 LexicalEnvironment 设置为 oldEnv。
    4. 返回 ? forDecl。
  9. 如果 isConst 是 false,则令 perIterationLets 为 boundNames;否则令 perIterationLets 为新的空 List。
  10. 如果存在第一个 Expression,则令 test 为第一个 Expression;否则令 test 为 empty。
  11. 如果存在第二个 Expression,则令 increment 为第二个 Expression;否则令 increment 为 empty。
  12. 令 bodyResult 为 Completion(ForBodyEvaluation(test, increment, Statement, perIterationLets, labelSet))。
  13. 将 bodyResult 设置为 Completion(DisposeResources(loopEnv.[[DisposableResourceStack]], bodyResult))。
  14. 断言:如果 bodyResult 是正常完成,则 bodyResult.[[Value]] 不是 empty。
  15. 将正在运行的执行上下文的 LexicalEnvironment 设置为 oldEnv。
  16. 返回 ? bodyResult。

14.7.4.3 ForBodyEvaluation ( test, increment, stmt, perIterationBindings, labelSet )

抽象操作 ForBodyEvaluation,接收参数 test ((an Expression Parse Node 或 empty))、increment ((an Expression Parse Node 或 empty))、stmt (a Statement Parse Node)、perIterationBindings (列表 (元素:String)) 和 labelSet (列表 (元素:String));返回值:(正常完成 (值:ECMAScript 语言值) 或 突兀完成)。 调用时执行以下步骤:

  1. 令 iterationResult 为 undefined。
  2. 执行 ? CreatePerIterationEnvironment(perIterationBindings)。
  3. 重复执行,
    1. 如果 test 不是 empty,则
      1. 令 testRef 为 ? test 的 Evaluation。
      2. 令 testValue 为 ? GetValue(testRef)。
      3. 如果 ToBoolean(testValue) 是 false,则返回 iterationResult。
    2. 令 result 为 Completion(stmt 的 Evaluation)。
    3. 如果 LoopContinues(result, labelSet) 是 false,则返回 ? UpdateEmpty(result, iterationResult)。
    4. 如果 result.[[Value]] 不是 empty,则将 iterationResult 设置为 result.[[Value]]。
    5. 执行 ? CreatePerIterationEnvironment(perIterationBindings)。
    6. 如果 increment 不是 empty,则
      1. 令 incrementRef 为 ? increment 的 Evaluation。
      2. 执行 ? GetValue(incrementRef)。

14.7.4.4 CreatePerIterationEnvironment ( perIterationBindings )

抽象操作 CreatePerIterationEnvironment,接收参数 perIterationBindings (列表 (元素:String));返回值:(正常完成 (值:unused) 或 抛出完成)。 调用时执行以下步骤:

  1. 如果 perIterationBindings 包含任何元素,则
    1. 令 lastIterationEnv 为正在运行的执行上下文的 LexicalEnvironment。
    2. 令 outer 为 lastIterationEnv.[[OuterEnv]]。
    3. 断言:outer 不是 null。
    4. 令 thisIterationEnv 为 NewDeclarativeEnvironment(outer)。
    5. 对 perIterationBindings 的每个元素 name,执行
      1. 执行 ! thisIterationEnv.CreateMutableBinding(name, false)。
      2. 令 lastValue 为 ? lastIterationEnv.GetBindingValue(name, true)。
      3. 执行 ! thisIterationEnv.InitializeBinding(name, lastValue)。
    6. 将正在运行的执行上下文的 LexicalEnvironment 设置为 thisIterationEnv。
  2. 返回 unused。

14.7.5 for-in、for-of 和 for-await-of 语句

语法

ForInOfStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] LeftHandSideExpression[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await, +Pattern] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await, ~Using] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await, +Pattern] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( [lookahead ≠ using of] ForDeclaration[?Yield, ?Await, +Using] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( [lookahead ≠ let] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( var ForBinding[?Yield, ?Await, +Pattern] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( [lookahead ≠ using of] ForDeclaration[?Yield, ?Await, +Using] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForDeclaration[Yield, Await, Using] : LetOrConst ForBinding[?Yield, ?Await, +Pattern] [+Using] using [no LineTerminator here] ForBinding[?Yield, ?Await, ~Pattern] [+Using, +Await] await [no LineTerminator here] using [no LineTerminator here] ForBinding[?Yield, +Await, ~Pattern] ForBinding[Yield, Await, Pattern] : BindingIdentifier[?Yield, ?Await] [+Pattern] BindingPattern[?Yield, ?Await] 注

本节由附录 B.3.5 扩展。

14.7.5.1 Static Semantics: 提前错误

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement 注

只有在实现了 B.3.1 中规定的扩展时,才需要应用此规则。

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement ForInOfStatement : for ( ForDeclaration in Expression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement

14.7.5.2 Static Semantics: IsDestructuring

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

MemberExpression : PrimaryExpression
  1. 如果 PrimaryExpression 是 ObjectLiteral 或 ArrayLiteral,则返回 true。
  2. 返回 false。
MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression
  1. 返回 false。
ForDeclaration : LetOrConst ForBinding
  1. 返回 ForBinding 的 IsDestructuring。
ForBinding : BindingIdentifier
  1. 返回 false。
ForBinding : BindingPattern
  1. 返回 true。
注

本节由附录 B.3.5 扩展。

14.7.5.3 Runtime Semantics: ForDeclarationBindingInitialization

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

ForDeclaration : LetOrConst ForBinding
  1. 返回 ? 以 value 和 envRecord 为参数对 ForBinding 执行 BindingInitialization 的结果。
ForDeclaration : using ForBinding await using ForBinding
  1. 抛出 SyntaxError 异常。

14.7.5.4 Runtime Semantics: ForDeclarationBindingInstantiation

语法制导操作 ForDeclarationBindingInstantiation,接收参数 envRecord (Declarative Environment 记录);返回值:unused。 它按以下产生式分别定义:

ForDeclaration : LetOrConst ForBinding
  1. 对 ForBinding 的 BoundNames 的每个元素 name,执行
    1. 如果 LetOrConst 的 IsConstantDeclaration 是 true,则
      1. 执行 ! envRecord.CreateImmutableBinding(name, true)。
    2. 否则,
      1. 执行 ! envRecord.CreateMutableBinding(name, false)。
  2. 返回 unused。
ForDeclaration : using ForBinding await using ForBinding
  1. 对 ForBinding 的 BoundNames 的每个元素 name,执行
    1. 执行 ! envRecord.CreateImmutableBinding(name, true)。
  2. 返回 unused。

14.7.5.5 Runtime Semantics: ForInOfLoopEvaluation

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

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement
  1. 令 keyResult 为 ? ForIn/OfHeadEvaluation(« », Expression, enumerate)。
  2. 返回 ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, enumerate, assignment, labelSet)。
ForInOfStatement : for ( var ForBinding in Expression ) Statement
  1. 令 keyResult 为 ? ForIn/OfHeadEvaluation(« », Expression, enumerate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, enumerate, var-binding, labelSet)。
ForInOfStatement : for ( ForDeclaration in Expression ) Statement
  1. 令 keyResult 为 ? ForIn/OfHeadEvaluation(ForDeclaration 的 BoundNames, Expression, enumerate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, enumerate, lexical-binding, labelSet)。
ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement
  1. 令 keyResult 为 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet)。
ForInOfStatement : for ( var ForBinding of AssignmentExpression ) Statement
  1. 令 keyResult 为 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, var-binding, labelSet)。
ForInOfStatement : for ( ForDeclaration of AssignmentExpression ) Statement
  1. 令 keyResult 为 ? ForIn/OfHeadEvaluation(ForDeclaration 的 BoundNames, AssignmentExpression, iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet)。
ForInOfStatement : for await ( LeftHandSideExpression of AssignmentExpression ) Statement
  1. 令 keyResult 为 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet, async)。
ForInOfStatement : for await ( var ForBinding of AssignmentExpression ) Statement
  1. 令 keyResult 为 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, var-binding, labelSet, async)。
ForInOfStatement : for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 令 keyResult 为 ? ForIn/OfHeadEvaluation(ForDeclaration 的 BoundNames, AssignmentExpression, async-iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet, async)。
注

本节由附录 B.3.5 扩展。

14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind )

抽象操作 ForIn/OfHeadEvaluation,接收参数 uninitializedBoundNames (列表 (元素:String))、expr ((an Expression Parse Node 或 an AssignmentExpression Parse Node)) 和 iterationKind ((enumerate、iterate 或 async-iterate));返回值:(正常完成 (值:Iterator 记录) 或 突兀完成)。 调用时执行以下步骤:

  1. 令 oldEnv 为正在运行的执行上下文的 LexicalEnvironment。
  2. 如果 uninitializedBoundNames 不为空,则
    1. 断言:uninitializedBoundNames 不包含重复条目。
    2. 令 newEnv 为 NewDeclarativeEnvironment(oldEnv)。
    3. 对 uninitializedBoundNames 的每个 String name,执行
      1. 执行 ! newEnv.CreateMutableBinding(name, false)。
    4. 将正在运行的执行上下文的 LexicalEnvironment 设置为 newEnv。
  3. 令 exprRef 为 Completion(expr 的 Evaluation)。
  4. 将正在运行的执行上下文的 LexicalEnvironment 设置为 oldEnv。
  5. 令 exprValue 为 ? GetValue(? exprRef)。
  6. 如果 iterationKind 是 enumerate,则
    1. 如果 exprValue 是 undefined 或 null,则
      1. 返回 Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }。
    2. 令 obj 为 ! ToObject(exprValue)。
    3. 令 iterator 为 EnumerateObjectProperties(obj)。
    4. 令 nextMethod 为 ! GetV(iterator, "next")。
    5. 返回 Iterator Record { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }。
  7. 断言:iterationKind 是 iterate 或 async-iterate。
  8. 如果 iterationKind 是 async-iterate,则令 iteratorKind 为 async。
  9. 否则,令 iteratorKind 为 sync。
  10. 返回 ? GetIterator(exprValue, iteratorKind)。

14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] )

抽象操作 ForIn/OfBodyEvaluation,接收参数 lhs (解析节点)、stmt (a Statement Parse Node)、iteratorRecord (Iterator 记录)、iterationKind ((enumerate 或 iterate))、lhsKind ((assignment、var-binding 或 lexical-binding)) 和 labelSet (列表 (元素:String))和可选参数 iteratorKind ((sync 或 async));返回值:(正常完成 (值:ECMAScript 语言值) 或 突兀完成)。 调用时执行以下步骤:

  1. 如果不存在 iteratorKind,则将 iteratorKind 设置为 sync。
  2. 令 oldEnv 为正在运行的执行上下文的 LexicalEnvironment。
  3. 令 iterationResult 为 undefined。
  4. 如果 lhsKind 是 lexical-binding,则
    1. 断言:lhs 是 ForDeclaration。
    2. 如果 lhs 的 IsAwaitUsingDeclaration 是 true,则
      1. 令 declKind 为 async-dispose。
    3. 否则如果 lhs 的 IsUsingDeclaration 是 true,则
      1. 令 declKind 为 sync-dispose。
    4. 否则,
      1. 令 declKind 为 normal。
  5. 否则,
    1. 令 declKind 为 normal。
  6. 令 destructuring 为 lhs 的 IsDestructuring。
  7. 如果 destructuring 是 true 且 lhsKind 是 assignment,则
    1. 断言:lhs 是 LeftHandSideExpression。
    2. 令 assignmentPattern 为 lhs 所覆盖的 AssignmentPattern。
  8. 重复执行,
    1. 令 nextResult 为 ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]])。
    2. 如果 iteratorKind 是 async,则将 nextResult 设置为 ? Await(nextResult)。
    3. 如果 nextResult 不是 Object,则抛出 TypeError 异常。
    4. 令 done 为 ? IteratorComplete(nextResult)。
    5. 如果 done 是 true,则返回 iterationResult。
    6. 令 nextValue 为 ? IteratorValue(nextResult)。
    7. 如果 lhsKind 是 assignment 或 var-binding,则
      1. 如果 destructuring 是 true,则
        1. 如果 lhsKind 是 assignment,则
          1. 令 status 为 Completion(以 nextValue 为参数对 assignmentPattern 执行 DestructuringAssignmentEvaluation 的结果)。
        2. 否则,
          1. 断言:lhsKind 是 var-binding。
          2. 断言:lhs 是 ForBinding。
          3. 令 status 为 Completion(以 nextValue 和 undefined 为参数对 lhs 执行 BindingInitialization 的结果)。
      2. 否则,
        1. 令 lhsRef 为 Completion(lhs 的 Evaluation)。(它可能被重复求值。)
        2. 如果 lhsKind 是 assignment 且 lhs 的 AssignmentTargetType 是 web-compat,则抛出 ReferenceError 异常。
        3. 如果 lhsRef 是突然完成,则
          1. 令 status 为 lhsRef。
        4. 否则,
          1. 令 status 为 Completion(PutValue(lhsRef.[[Value]], nextValue))。
      3. 令 iterationEnv 为 undefined。
    8. 否则,
      1. 断言:lhsKind 是 lexical-binding。
      2. 断言:lhs 是 ForDeclaration。
      3. 令 iterationEnv 为 NewDeclarativeEnvironment(oldEnv)。
      4. 以 iterationEnv 为参数对 lhs 执行 ForDeclarationBindingInstantiation。
      5. 将正在运行的执行上下文的 LexicalEnvironment 设置为 iterationEnv。
      6. 如果 destructuring 是 true,则
        1. 令 status 为 Completion(以 nextValue 和 iterationEnv 为参数对 lhs 执行 ForDeclarationBindingInitialization 的结果)。
      7. 否则,
        1. 断言:lhs 绑定单个名称。
        2. 令 lhsName 为 lhs 的 BoundNames 的唯一元素。
        3. 令 lhsRef 为 ! ResolveBinding(lhsName)。
        4. 如果 declKind 不是 normal,则
          1. 断言:IsUnresolvableReference(lhsRef) 是 false。
          2. 令 base 为 lhsRef.[[Base]]。
          3. 断言:base 是 Declarative Environment Record。
          4. 令 status 为 Completion(AddDisposableResource(base.[[DisposableResourceStack]], nextValue, declKind))。
        5. 否则,
          1. 令 status 为 NormalCompletion(unused)。
        6. 如果 status 是正常完成,则
          1. 将 status 设置为 Completion(InitializeReferencedBinding(lhsRef, nextValue))。
    9. 如果 status 是突然完成,则
      1. 如果 iterationEnv 不是 undefined,则
        1. 将 status 设置为 Completion(DisposeResources(iterationEnv.[[DisposableResourceStack]], status))。
        2. 断言:status 是突然完成。
      2. 将正在运行的执行上下文的 LexicalEnvironment 设置为 oldEnv。
      3. 如果 iterationKind 是 enumerate,则返回 ? status。
      4. 断言:iterationKind 是 iterate。
      5. 如果 iteratorKind 是 async,则返回 ? AsyncIteratorClose(iteratorRecord, status)。
      6. 返回 ? IteratorClose(iteratorRecord, status)。
    10. 令 result 为 Completion(stmt 的 Evaluation)。
    11. 如果 iterationEnv 不是 undefined,则
      1. 将 result 设置为 Completion(DisposeResources(iterationEnv.[[DisposableResourceStack]], result))。
    12. 将正在运行的执行上下文的 LexicalEnvironment 设置为 oldEnv。
    13. 如果 LoopContinues(result, labelSet) 是 false,则
      1. 将 status 设置为 Completion(UpdateEmpty(result, iterationResult))。
      2. 如果 iterationKind 是 enumerate,则返回 ? status。
      3. 断言:iterationKind 是 iterate。
      4. 如果 iteratorKind 是 async,则返回 ? AsyncIteratorClose(iteratorRecord, status)。
      5. 返回 ? IteratorClose(iteratorRecord, status)。
    14. 如果 result.[[Value]] 不是 empty,则将 iterationResult 设置为 result.[[Value]]。

14.7.5.8 Runtime Semantics: Evaluation

BindingIdentifier : Identifier yield await
  1. 令 name 为 BindingIdentifier 的 StringValue。
  2. 返回 ? ResolveBinding(name)。

14.7.5.9 EnumerateObjectProperties ( obj )

抽象操作 EnumerateObjectProperties,接收参数 obj (Object);返回值:迭代器对象。 调用时执行以下步骤:

  1. 返回一个迭代器对象,其 next 方法迭代 obj 的所有可枚举属性中值为 String 的键。该迭代器对象永远无法被 ECMAScript 代码直接访问。枚举属性的机制和顺序未作规定,但必须符合下述规则。

该迭代器的 throw 和 return 方法为 null,且永远不会被调用。迭代器的 next 方法处理对象属性,以确定是否应将属性键作为迭代器值返回。返回的属性键不包括 Symbol 键。目标对象的属性可以在枚举期间被删除。在迭代器的 next 方法处理某个属性之前删除该属性时,会忽略该属性。如果在枚举期间向目标对象添加新属性,则不保证在当前枚举中处理新添加的属性。在任意一次枚举中,一个属性名称最多由迭代器的 next 方法返回一次。

枚举目标对象的属性包括递归枚举其原型、原型的原型,依此类推;但如果原型的某个属性与迭代器的 next 方法已经处理过的属性具有相同名称,则不会处理该原型属性。在确定原型对象的某个属性是否已经被处理时,不考虑 [[Enumerable]] 特性的值。必须通过以原型对象为参数调用 EnumerateObjectProperties 来获取原型对象的可枚举属性名称。EnumerateObjectProperties 必须通过调用目标对象的 [[OwnPropertyKeys]] 内部方法来获取其自有属性键。目标对象的属性特性必须通过调用其 [[GetOwnProperty]] 内部方法获取。

此外,如果 obj 及其原型链中的任何对象都不是 Proxy 异质对象、TypedArray、模块命名空间异质对象或实现提供的异质对象,则在发生以下任一情况之前,该迭代器的行为必须与由 CreateForInIterator(obj) 给出的迭代器相同:

  • obj 或其原型链中某个对象的 [[Prototype]] 内部槽值发生变化,
  • 从 obj 或其原型链中的某个对象移除属性,
  • 向 obj 原型链中的某个对象添加属性,或
  • obj 或其原型链中某个对象的某个属性的 [[Enumerable]] 特性值发生变化。
注 1

ECMAScript 实现无需直接实现 14.7.5.10.2.1 中的算法。它们可以选择任何实现,只要在不违反上一段中任何约束的情况下,其行为不会偏离该算法。

以下是符合这些规则的 ECMAScript 生成器函数的非规范性定义:

function* EnumerateObjectProperties(obj) {
  const visited = new Set();
  for (const key of Reflect.ownKeys(obj)) {
    if (typeof key === "symbol") continue;
    const desc = Reflect.getOwnPropertyDescriptor(obj, key);
    if (desc) {
      visited.add(key);
      if (desc.enumerable) yield key;
    }
  }
  const proto = Reflect.getPrototypeOf(obj);
  if (proto === null) return;
  for (const protoKey of EnumerateObjectProperties(proto)) {
    if (!visited.has(protoKey)) yield protoKey;
  }
}
注 2
对于实现无需匹配 CreateForInIterator 的异质对象列表之所以如此选择,是因为历史上各实现对这些情况的行为存在差异,而对所有其他情况的行为一致。

14.7.5.10 For-In Iterator 对象

For-In Iterator 是表示对某个特定对象进行一次特定迭代的对象。For-In Iterator 对象永远无法被 ECMAScript 代码直接访问;它们仅用于说明 EnumerateObjectProperties 的行为。

14.7.5.10.1 CreateForInIterator ( obj )

抽象操作 CreateForInIterator,接收参数 obj (Object);返回值:a For-In Iterator。 它用于创建一个 For-In Iterator 对象,该对象按特定顺序迭代 obj 的自有和继承的可枚举字符串属性。 调用时执行以下步骤:

  1. 令 iterator 为 OrdinaryObjectCreate(%ForInIteratorPrototype%, « [[Object]], [[ObjectWasVisited]], [[VisitedKeys]], [[RemainingKeys]] »)。
  2. 将 iterator.[[Object]] 设置为 obj。
  3. 将 iterator.[[ObjectWasVisited]] 设置为 false。
  4. 将 iterator.[[VisitedKeys]] 设置为新的空 List。
  5. 将 iterator.[[RemainingKeys]] 设置为新的空 List。
  6. 返回 iterator。

14.7.5.10.2 %ForInIteratorPrototype% 对象

%ForInIteratorPrototype% 对象:

14.7.5.10.2.1 %ForInIteratorPrototype%.next ( )

  1. 令 iterator 为 this 值。
  2. 断言:iterator 是 Object。
  3. 断言:iterator 具有 For-In Iterator 实例的所有内部槽(14.7.5.10.3)。
  4. 令 obj 为 iterator.[[Object]]。
  5. 重复执行,
    1. 如果 iterator.[[ObjectWasVisited]] 是 false,则
      1. 令 keys 为 ? obj.[[OwnPropertyKeys]]()。
      2. 对 keys 的每个元素 key,执行
        1. 如果 key 是 String,则
          1. 将 key 追加到 iterator.[[RemainingKeys]]。
      3. 将 iterator.[[ObjectWasVisited]] 设置为 true。
    2. 当 iterator.[[RemainingKeys]] 不为空时,重复执行,
      1. 令 key 为 iterator.[[RemainingKeys]] 的第一个元素。
      2. 从 iterator.[[RemainingKeys]] 中移除第一个元素。
      3. 如果 iterator.[[VisitedKeys]] 不包含 key,则
        1. 令 propertyDesc 为 ? obj.[[GetOwnProperty]](key)。
        2. 如果 propertyDesc 不是 undefined,则
          1. 将 key 追加到 iterator.[[VisitedKeys]]。
          2. 如果 propertyDesc.[[Enumerable]] 是 true,则返回 CreateIteratorResultObject(key, false)。
    3. 将 obj 设置为 ? obj.[[GetPrototypeOf]]()。
    4. 将 iterator.[[Object]] 设置为 obj。
    5. 将 iterator.[[ObjectWasVisited]] 设置为 false。
    6. 如果 obj 是 null,则返回 CreateIteratorResultObject(undefined, true)。

14.7.5.10.3 For-In Iterator 实例的属性

For-In Iterator 实例是从 %ForInIteratorPrototype% 内在对象继承属性的普通对象。For-In Iterator 实例最初使用 表 34 中列出的内部槽创建。

表 34: For-In Iterator 实例的内部槽
内部槽 类型 描述
[[Object]] Object 正在迭代其属性的 Object 值。
[[ObjectWasVisited]] Boolean 如果迭代器已在 [[Object]] 上调用 [[OwnPropertyKeys]],则为 true;否则为 false。
[[VisitedKeys]] String 的 List 到目前为止由此迭代器发出的值。
[[RemainingKeys]] String 的 List 在迭代其原型的属性(如果其原型不是 null)之前,当前对象尚待发出的值。

14.8 continue 语句

语法

ContinueStatement[Yield, Await] : continue ; continue [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ;

14.8.1 Static Semantics: 提前错误

ContinueStatement : continue ; continue LabelIdentifier ;

14.8.2 Runtime Semantics: Evaluation

ContinueStatement : continue ;
  1. 返回 Completion Record { [[Type]]: continue, [[Value]]: empty, [[Target]]: empty }。
ContinueStatement : continue LabelIdentifier ;
  1. 令 label 为 LabelIdentifier 的 StringValue。
  2. 返回 Completion Record { [[Type]]: continue, [[Value]]: empty, [[Target]]: label }。

14.9 break 语句

语法

BreakStatement[Yield, Await] : break ; break [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ;

14.9.1 Static Semantics: 提前错误

BreakStatement : break ;

14.9.2 Runtime Semantics: Evaluation

BreakStatement : break ;
  1. 返回 Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }。
BreakStatement : break LabelIdentifier ;
  1. 令 label 为 LabelIdentifier 的 StringValue。
  2. 返回 Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: label }。

14.10 return 语句

语法

ReturnStatement[Yield, Await] : return ; return [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; 注

return 语句会使函数停止执行,并且在大多数情况下向调用方返回一个值。如果省略 Expression,则返回值为 undefined。否则,返回值为 Expression 的值。根据周围上下文,return 语句实际上可能不会向调用方返回值。例如,在 try 块中,return 语句的 Completion Record 可能在对 finally 块求值期间被另一个 Completion Record 替换。

14.10.1 Runtime Semantics: Evaluation

ReturnStatement : return ;
  1. 返回 ReturnCompletion(undefined)。
ReturnStatement : return Expression ;
  1. 令 exprRef 为 ? Expression 的 Evaluation。
  2. 令 exprValue 为 ? GetValue(exprRef)。
  3. 如果 GetGeneratorKind() 是 async,则将 exprValue 设置为 ? Await(exprValue)。
  4. 返回 ReturnCompletion(exprValue)。

14.11 with 语句

注 1

不鼓励在新的 ECMAScript 代码中使用旧式 with 语句。请考虑同时允许用于严格模式代码和非严格代码的替代方案,例如 解构赋值。

语法

WithStatement[Yield, Await, Return] : with ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] 注 2

with 语句会为计算得到的对象向正在运行的执行上下文的词法环境添加一个 Object Environment Record。然后,它使用这一扩展后的词法环境执行语句。最后,它恢复原始词法环境。

14.11.1 Static Semantics: 提前错误

WithStatement : with ( Expression ) Statement 注

只有在实现了 B.3.1 中规定的扩展时,才需要应用第二条规则。

14.11.2 Runtime Semantics: Evaluation

WithStatement : with ( Expression ) Statement
  1. 令 value 为 ? Expression 的 Evaluation。
  2. 令 obj 为 ? ToObject(? GetValue(value))。
  3. 令 oldEnv 为正在运行的执行上下文的 LexicalEnvironment。
  4. 令 newEnv 为 NewObjectEnvironment(obj, true, oldEnv)。
  5. 将正在运行的执行上下文的 LexicalEnvironment 设置为 newEnv。
  6. 令 stmtCompletion 为 Completion(Statement 的 Evaluation)。
  7. 将正在运行的执行上下文的 LexicalEnvironment 设置为 oldEnv。
  8. 返回 ? UpdateEmpty(stmtCompletion, undefined)。
注

无论控制如何离开嵌入的 Statement,无论是正常离开、通过某种形式的突然完成还是异常,LexicalEnvironment 始终都会恢复为其先前状态。

14.12 switch 语句

语法

SwitchStatement[Yield, Await, Return] : switch ( Expression[+In, ?Yield, ?Await] ) CaseBlock[?Yield, ?Await, ?Return] CaseBlock[Yield, Await, Return] : { CaseClauses[?Yield, ?Await, ?Return]opt } { CaseClauses[?Yield, ?Await, ?Return]opt DefaultClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return]opt } CaseClauses[Yield, Await, Return] : CaseClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return] CaseClause[?Yield, ?Await, ?Return] CaseClause[Yield, Await, Return] : case Expression[+In, ?Yield, ?Await] : StatementList[?Yield, ?Await, ?Return]opt DefaultClause[Yield, Await, Return] : default : StatementList[?Yield, ?Await, ?Return]opt

14.12.1 Static Semantics: 提前错误

SwitchStatement : switch ( Expression ) CaseBlock CaseClause : case Expression : StatementList DefaultClause : default : StatementList

14.12.2 Runtime Semantics: CaseBlockEvaluation

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

CaseBlock : { }
  1. 返回 undefined。
CaseBlock : { CaseClauses }
  1. 令 resultValue 为 undefined。
  2. 令 caseClauses 为 CaseClauses 中按源文本顺序排列的 CaseClause 项的 List。
  3. 令 found 为 false。
  4. 对 caseClauses 的每个 CaseClause clause,执行
    1. 如果 found 是 false,则
      1. 将 found 设置为 ? CaseClauseIsSelected(clause, input)。
    2. 如果 found 是 true,则
      1. 令 completion 为 Completion(clause 的 Evaluation)。
      2. 如果 completion.[[Value]] 不是 empty,则将 resultValue 设置为 completion.[[Value]]。
      3. 如果 completion 是突然完成,则返回 ? UpdateEmpty(completion, resultValue)。
  5. 返回 resultValue。
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 令 resultValue 为 undefined。
  2. 如果存在第一个 CaseClauses,则
    1. 令 caseClauses 为第一个 CaseClauses 中按源文本顺序排列的 CaseClause 项的 List。
  3. 否则,
    1. 令 caseClauses 为新的空 List。
  4. 令 found 为 false。
  5. 对 caseClauses 的每个 CaseClause clause,执行
    1. 如果 found 是 false,则
      1. 将 found 设置为 ? CaseClauseIsSelected(clause, input)。
    2. 如果 found 是 true,则
      1. 令 completion 为 Completion(clause 的 Evaluation)。
      2. 如果 completion.[[Value]] 不是 empty,则将 resultValue 设置为 completion.[[Value]]。
      3. 如果 completion 是突然完成,则返回 ? UpdateEmpty(completion, resultValue)。
  6. 令 foundInB 为 false。
  7. 如果存在第二个 CaseClauses,则
    1. 令 secondCaseClauses 为第二个 CaseClauses 中按源文本顺序排列的 CaseClause 项的 List。
  8. 否则,
    1. 令 secondCaseClauses 为新的空 List。
  9. 如果 found 是 false,则
    1. 对 secondCaseClauses 的每个 CaseClause clause,执行
      1. 如果 foundInB 是 false,则
        1. 将 foundInB 设置为 ? CaseClauseIsSelected(clause, input)。
      2. 如果 foundInB 是 true,则
        1. 令 completion 为 Completion(CaseClause clause 的 Evaluation)。
        2. 如果 completion.[[Value]] 不是 empty,则将 resultValue 设置为 completion.[[Value]]。
        3. 如果 completion 是突然完成,则返回 ? UpdateEmpty(completion, resultValue)。
  10. 如果 foundInB 是 true,则返回 resultValue。
  11. 令 defaultR 为 Completion(DefaultClause 的 Evaluation)。
  12. 如果 defaultR.[[Value]] 不是 empty,则将 resultValue 设置为 defaultR.[[Value]]。
  13. 如果 defaultR 是突然完成,则返回 ? UpdateEmpty(defaultR, resultValue)。
  14. 注:以下是对第二个 CaseClauses 的另一次完整迭代。
  15. 对 secondCaseClauses 的每个 CaseClause clause,执行
    1. 令 completion 为 Completion(CaseClause clause 的 Evaluation)。
    2. 如果 completion.[[Value]] 不是 empty,则将 resultValue 设置为 completion.[[Value]]。
    3. 如果 completion 是突然完成,则返回 ? UpdateEmpty(completion, resultValue)。
  16. 返回 resultValue。

14.12.3 CaseClauseIsSelected ( caseClauseNode, input )

抽象操作 CaseClauseIsSelected,接收参数 caseClauseNode (a CaseClause Parse Node) 和 input (ECMAScript 语言值);返回值:(正常完成 (值:Boolean) 或 突兀完成)。 它确定 caseClauseNode 是否与 input 匹配。 调用时执行以下步骤:

  1. 断言:caseClauseNode 是产生式 CaseClause : case Expression : StatementListopt 的实例。
  2. 令 exprRef 为 ? caseClauseNode 的 Expression 的 Evaluation。
  3. 令 clauseSelector 为 ? GetValue(exprRef)。
  4. 返回 IsStrictlyEqual(input, clauseSelector)。
注

此操作不会执行 caseClauseNode 的 StatementList(如果存在)。CaseBlock 算法使用其返回值来确定从哪个 StatementList 开始执行。

14.12.4 Runtime Semantics: Evaluation

SwitchStatement : switch ( Expression ) CaseBlock
  1. 令 exprRef 为 ? Expression 的 Evaluation。
  2. 令 switchValue 为 ? GetValue(exprRef)。
  3. 令 oldEnv 为正在运行的执行上下文的 LexicalEnvironment。
  4. 令 blockEnv 为 NewDeclarativeEnvironment(oldEnv)。
  5. 执行 BlockDeclarationInstantiation(CaseBlock, blockEnv)。
  6. 将正在运行的执行上下文的 LexicalEnvironment 设置为 blockEnv。
  7. 令 blockResult 为 Completion(以 switchValue 为参数对 CaseBlock 执行 CaseBlockEvaluation 的结果)。
  8. 断言:blockEnv.[[DisposableResourceStack]] 是空 List。
  9. 将正在运行的执行上下文的 LexicalEnvironment 设置为 oldEnv。
  10. 返回 blockResult。
注

无论控制如何离开 SwitchStatement,LexicalEnvironment 始终都会恢复为其先前状态。

CaseClause : case Expression :
  1. 返回 empty。
CaseClause : case Expression : StatementList
  1. 返回 ? StatementList 的 Evaluation。
DefaultClause : default :
  1. 返回 empty。
DefaultClause : default : StatementList
  1. 返回 ? StatementList 的 Evaluation。

14.13 带标签语句

语法

LabelledStatement[Yield, Await, Return] : LabelIdentifier[?Yield, ?Await] : LabelledItem[?Yield, ?Await, ?Return] LabelledItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] FunctionDeclaration[?Yield, ?Await, ~Default] 注

Statement 可以以标签作为前缀。带标签语句仅与带标签的 break 和 continue 语句一起使用。ECMAScript 没有 goto 语句。一个 Statement 可以是 LabelledStatement 的一部分,而后者本身又可以是另一个 LabelledStatement 的一部分,依此类推。在描述各个语句的语义时,以这种方式引入的标签统称为“当前标签集”。

14.13.1 Static Semantics: 提前错误

LabelledItem : FunctionDeclaration

14.13.2 Static Semantics: IsLabelledFunction ( stmt )

抽象操作 IsLabelledFunction,接收参数 stmt (a Statement Parse Node);返回值:Boolean。 调用时执行以下步骤:

  1. 如果 stmt 不是 LabelledStatement,则返回 false。
  2. 令 item 为 stmt 的 LabelledItem。
  3. 如果 item 是 LabelledItem : FunctionDeclaration ,则返回 true。
  4. 令 subStmt 为 item 的 Statement。
  5. 返回 IsLabelledFunction(subStmt)。

14.13.3 Runtime Semantics: Evaluation

LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 ? 以 « » 为参数对当前 LabelledStatement 执行 LabelledEvaluation 的结果。

14.13.4 Runtime Semantics: LabelledEvaluation

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

BreakableStatement : IterationStatement
  1. 令 stmtResult 为 Completion(以 labelSet 为参数对 IterationStatement 执行 LoopEvaluation 的结果)。
  2. 如果 stmtResult 是 break 完成,则
    1. 如果 stmtResult.[[Target]] 是 empty,则
      1. 如果 stmtResult.[[Value]] 是 empty,则将 stmtResult 设置为 NormalCompletion(undefined)。
      2. 否则,将 stmtResult 设置为 NormalCompletion(stmtResult.[[Value]])。
  3. 返回 ? stmtResult。
BreakableStatement : SwitchStatement
  1. 令 stmtResult 为 Completion(SwitchStatement 的 Evaluation)。
  2. 如果 stmtResult 是 break 完成,则
    1. 如果 stmtResult.[[Target]] 是 empty,则
      1. 如果 stmtResult.[[Value]] 是 empty,则将 stmtResult 设置为 NormalCompletion(undefined)。
      2. 否则,将 stmtResult 设置为 NormalCompletion(stmtResult.[[Value]])。
  3. 返回 ? stmtResult。
注 1

BreakableStatement 是可以通过无标签 BreakStatement 退出的语句。

LabelledStatement : LabelIdentifier : LabelledItem
  1. 令 label 为 LabelIdentifier 的 StringValue。
  2. 令 newLabelSet 为 labelSet 与 « label » 的列表连接。
  3. 令 stmtResult 为 Completion(以 newLabelSet 为参数对 LabelledItem 执行 LabelledEvaluation 的结果)。
  4. 如果 stmtResult 是 break 完成且 stmtResult.[[Target]] 是 label,则
    1. 将 stmtResult 设置为 NormalCompletion(stmtResult.[[Value]])。
  5. 返回 ? stmtResult。
LabelledItem : FunctionDeclaration
  1. 返回 ? FunctionDeclaration 的 Evaluation。
Statement : BlockStatement VariableStatement EmptyStatement ExpressionStatement IfStatement ContinueStatement BreakStatement ReturnStatement WithStatement ThrowStatement TryStatement DebuggerStatement
  1. 返回 ? Statement 的 Evaluation。
注 2

Statement 中只有两个产生式具有 LabelledEvaluation 的特殊语义,即 BreakableStatement 和 LabelledStatement。

14.14 throw 语句

语法

ThrowStatement[Yield, Await] : throw [no LineTerminator here] Expression[+In, ?Yield, ?Await] ;

14.14.1 Runtime Semantics: Evaluation

ThrowStatement : throw Expression ;
  1. 令 exprRef 为 ? Expression 的 Evaluation。
  2. 令 exprValue 为 ? GetValue(exprRef)。
  3. 抛出 exprValue。

14.15 try 语句

语法

TryStatement[Yield, Await, Return] : try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] Catch[Yield, Await, Return] : catch ( CatchParameter[?Yield, ?Await] ) Block[?Yield, ?Await, ?Return] catch Block[?Yield, ?Await, ?Return] Finally[Yield, Await, Return] : finally Block[?Yield, ?Await, ?Return] CatchParameter[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] 注

try 语句包围一段可能发生异常状况的代码块,例如运行时错误或 throw 语句。catch 子句提供异常处理代码。当 catch 子句捕获异常时,其 CatchParameter 会绑定到该异常。

14.15.1 Static Semantics: 提前错误

Catch : catch ( CatchParameter ) Block

14.15.2 Runtime Semantics: CatchClauseEvaluation

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

Catch : catch ( CatchParameter ) Block
  1. 令 oldEnv 为正在运行的执行上下文的 LexicalEnvironment。
  2. 令 catchEnv 为 NewDeclarativeEnvironment(oldEnv)。
  3. 对 CatchParameter 的 BoundNames 的每个元素 argName,执行
    1. 执行 ! catchEnv.CreateMutableBinding(argName, false)。
  4. 将正在运行的执行上下文的 LexicalEnvironment 设置为 catchEnv。
  5. 令 status 为 Completion(以 thrownValue 和 catchEnv 为参数对 CatchParameter 执行 BindingInitialization 的结果)。
  6. 如果 status 是突然完成,则
    1. 将正在运行的执行上下文的 LexicalEnvironment 设置为 oldEnv。
    2. 返回 ? status。
  7. 令 blockCompletion 为 Completion(Block 的 Evaluation)。
  8. 将正在运行的执行上下文的 LexicalEnvironment 设置为 oldEnv。
  9. 返回 ? blockCompletion。
Catch : catch Block
  1. 返回 ? Block 的 Evaluation。
注

无论控制如何离开 Block,LexicalEnvironment 始终都会恢复为其先前状态。

14.15.3 Runtime Semantics: Evaluation

TryStatement : try Block Catch
  1. 令 blockResult 为 Completion(Block 的 Evaluation)。
  2. 如果 blockResult 是抛出完成,则令 catchResult 为 Completion(以 blockResult.[[Value]] 为参数对 Catch 执行 CatchClauseEvaluation 的结果)。
  3. 否则,令 catchResult 为 blockResult。
  4. 返回 ? UpdateEmpty(catchResult, undefined)。
TryStatement : try Block Finally
  1. 令 blockResult 为 Completion(Block 的 Evaluation)。
  2. 令 finallyResult 为 Completion(Finally 的 Evaluation)。
  3. 如果 finallyResult 是正常完成,则将 finallyResult 设置为 blockResult。
  4. 返回 ? UpdateEmpty(finallyResult, undefined)。
TryStatement : try Block Catch Finally
  1. 令 blockResult 为 Completion(Block 的 Evaluation)。
  2. 如果 blockResult 是抛出完成,则令 catchResult 为 Completion(以 blockResult.[[Value]] 为参数对 Catch 执行 CatchClauseEvaluation 的结果)。
  3. 否则,令 catchResult 为 blockResult。
  4. 令 finallyResult 为 Completion(Finally 的 Evaluation)。
  5. 如果 finallyResult 是正常完成,则将 finallyResult 设置为 catchResult。
  6. 返回 ? UpdateEmpty(finallyResult, undefined)。

14.16 debugger 语句

语法

DebuggerStatement : debugger ;

14.16.1 Runtime Semantics: Evaluation

注

对 DebuggerStatement 求值时,如果在调试器下运行,实现可以触发断点。如果调试器不存在或未处于活动状态,则此语句没有可观察效果。

DebuggerStatement : debugger ;
  1. 如果实现定义的调试设施可用并且已启用,则
    1. 执行实现定义的调试操作。
    2. 返回一个新的实现定义 Completion Record。
  2. 返回 empty。