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. 返回 ? FunctionDeclarationEvaluation
BreakableStatement : IterationStatement SwitchStatement
  1. newLabelSet 为新的空 List
  2. 返回 ? 以 newLabelSet 为实参执行此 BreakableStatementLabelledEvaluation

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. blockEnvNewDeclarativeEnvironment(oldEnv)。
  3. 执行 BlockDeclarationInstantiation(StatementList, blockEnv)。
  4. 将运行中执行上下文的 LexicalEnvironment 设置为 blockEnv
  5. blockValueCompletion(StatementList 的求值)。
  6. blockValue 设置为 Completion(DisposeResources(blockEnv.[[DisposableResourceStack]], blockValue))。
  7. 将运行中执行上下文的 LexicalEnvironment 设置为 oldEnv
  8. 返回 ? blockValue
Note 1

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

StatementList : StatementList StatementListItem
  1. sl 为 ? StatementListEvaluation
  2. sCompletion(StatementListItemEvaluation)。
  3. 返回 ? UpdateEmpty(s, sl)。
Note 2

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

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

14.2.3 BlockDeclarationInstantiation ( code, envRecord )

The abstract operation BlockDeclarationInstantiation takes arguments code (a Parse Node) and envRecord (a Declarative Environment Record) and returns unused. code 是对应于块体的 Parse NodeenvRecord 是要在其中创建绑定的 Environment Record

Note

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

它在被调用时执行以下步骤:

  1. declscodeLexicallyScopedDeclarations
  2. privateEnv 为正在运行的执行上下文的 PrivateEnvironment。
  3. decls 的每个元素 decl,执行:
    1. declBoundNames 的每个元素 name,执行:
      1. 如果 declIsConstantDeclarationtrue,则
        1. 执行 ! envRecord.CreateImmutableBinding(name, true)。
      2. 否则,
        1. 如果宿主是 Web 浏览器,或以其他方式支持 块级函数声明的 Web 遗留兼容性语义,则
          1. 如果 ! envRecord.HasBinding(name) 为 false,则
            1. 执行 ! envRecord.CreateMutableBinding(name, false)。
        2. 否则,
          1. 执行 ! envRecord.CreateMutableBinding(name, false)。
    2. 如果 declFunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclaration,则
      1. funcNamedeclBoundNames 的唯一元素。
      2. funcObj 为使用参数 envRecordprivateEnvdecl 执行 InstantiateFunctionObject 的结果。
      3. 如果宿主是 Web 浏览器,或以其他方式支持 块级函数声明的 Web 遗留兼容性语义,则
        1. 如果 envRecordfuncName 的绑定是未初始化绑定,则
          1. 执行 ! envRecord.InitializeBinding(funcName, funcObj)。
        2. 否则,
          1. 断言:declFunctionDeclaration
          2. 执行 ! envRecord.SetMutableBinding(funcName, funcObj, false)。
      4. 否则,
        1. 执行 ! envRecord.InitializeBinding(funcName, funcObj)。
  4. 返回 unused

14.3 声明和变量语句

14.3.1 Let、Const、Using 和 Await Using 声明

Note

letconstusingawait using 声明定义的变量,其作用域为运行中执行上下文的 LexicalEnvironment。这些变量会在其包含的环境记录实例化时创建,但在变量的 LexicalBinding 被求值之前,不得以任何方式访问。由带有 InitializerLexicalBinding 定义的变量,会在 LexicalBinding 被求值时被赋予其 InitializerAssignmentExpression 的值,而不是在变量创建时赋值。如果 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: 求值

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

The syntax-directed operation BindingEvaluation takes argument kind (normalsync-disposeasync-dispose,) and returns 含有 unused正常完成,或突兀完成. It is defined piecewise over the following productions:

BindingList : BindingList , LexicalBinding
  1. 执行以 kind 为参数的派生 BindingList 的 ? BindingEvaluation
  2. 返回以 kind 为参数的 LexicalBinding 的 ? BindingEvaluation
LexicalBinding : BindingIdentifier
  1. 断言:kindnormal
  2. lhs 为 ! ResolveBinding(BindingIdentifierStringValue)。
  3. 执行 ! InitializeReferencedBinding(lhs, undefined)。
  4. 返回 unused
Note

一条静态语义规则确保这种形式的 LexicalBinding 永远不会出现在 constusingawait using 声明中。

LexicalBinding : BindingIdentifier Initializer
  1. bindingIdBindingIdentifierStringValue
  2. lhs 为 ! ResolveBinding(bindingId)。
  3. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true,则
    1. value 为以 bindingId 为参数的 Initializer 的 ? NamedEvaluation
  4. 否则,
    1. rhsInitializer 的 ? Evaluation
    2. value 为 ? GetValue(rhs)。
  5. 如果 kind 不是 normal,则
    1. 断言:IsUnresolvableReference(lhs) 是 false
    2. baselhs.[[Base]]
    3. 断言:base 是声明式环境记录。
    4. 执行 ? AddDisposableResource(base.[[DisposableResourceStack]], value, kind)。
  6. 执行 ? InitializeReferencedBinding(lhs, value)。
  7. 返回 unused
LexicalBinding : BindingPattern Initializer
  1. 断言:kindnormal
  2. rhsInitializer 的 ? Evaluation
  3. value 为 ? GetValue(rhs)。
  4. envRecord 为运行中执行上下文的 LexicalEnvironment。
  5. 返回以 valueenvRecord 为参数的 BindingPattern 的 ? BindingInitialization

14.3.2 变量语句

Note

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

语法

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. 执行 ? VariableDeclarationListEvaluation
  2. 返回 empty
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. 执行 ? VariableDeclarationListEvaluation
  2. 返回 ? VariableDeclarationEvaluation
VariableDeclaration : BindingIdentifier
  1. 返回 empty
VariableDeclaration : BindingIdentifier Initializer
  1. bindingIdBindingIdentifierStringValue
  2. lhs 为 ? ResolveBinding(bindingId)。
  3. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true,则
    1. value 为 ? 以 bindingId 为实参执行 InitializerNamedEvaluation
  4. 否则,
    1. rhs 为 ? InitializerEvaluation
    2. value 为 ? GetValue(rhs)。
  5. 执行 ? PutValue(lhs, value)。
  6. 返回 empty
Note

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

VariableDeclaration : BindingPattern Initializer
  1. rhs 为 ? InitializerEvaluation
  2. rightValue 为 ? GetValue(rhs)。
  3. 返回 ? 以 rightValueundefined 为实参执行 BindingPatternBindingInitialization

14.3.3 解构绑定模式

语法

BindingPattern[Yield, Await] : ObjectBindingPattern[?Yield, ?Await] ArrayBindingPattern[?Yield, ?Await] ObjectBindingPattern[Yield, Await] : { } { BindingRestProperty[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] , BindingRestProperty[?Yield, ?Await]opt } 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

The syntax-directed operation PropertyBindingInitialization takes arguments value (an ECMAScript language value) and envRecord (an Environment Record or undefined) and returns either a normal completion containing a List of property keys or an abrupt completion. 它收集所有被绑定属性名的列表。 It is defined piecewise over the following productions:

BindingPropertyList : BindingPropertyList , BindingProperty
  1. boundNames 为 ? 以 valueenvRecord 为实参执行 BindingPropertyListPropertyBindingInitialization
  2. nextNames 为 ? 以 valueenvRecord 为实参执行 BindingPropertyPropertyBindingInitialization
  3. 返回 boundNamesnextNames列表连接
BindingProperty : SingleNameBinding
  1. nameSingleNameBindingBoundNames 的唯一元素。
  2. 执行 ? 以 valueenvRecordname 为实参执行 SingleNameBindingKeyedBindingInitialization
  3. 返回 « name »。
BindingProperty : PropertyName : BindingElement
  1. propertyKey 为 ? PropertyNameEvaluation
  2. 执行 ? 以 valueenvRecordpropertyKey 为实参执行 BindingElementKeyedBindingInitialization
  3. 返回 « propertyKey »。

14.3.3.2 Runtime Semantics: RestBindingInitialization

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

BindingRestProperty : ... BindingIdentifier
  1. lhs 为 ? ResolveBinding(BindingIdentifierStringValue, envRecord)。
  2. restObjOrdinaryObjectCreate(%Object.prototype%)。
  3. 执行 ? CopyDataProperties(restObj, value, excludedNames)。
  4. 如果 envRecordundefined,则返回 ? PutValue(lhs, restObj)。
  5. 返回 ? InitializeReferencedBinding(lhs, restObj)。

14.3.3.3 Runtime Semantics: KeyedBindingInitialization

The syntax-directed operation KeyedBindingInitialization takes arguments value (an ECMAScript language value), envRecord (an Environment Record or undefined), and propertyName (a property key) and returns either a normal completion containing unused or an abrupt completion.

Note

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

It is defined piecewise over the following productions:

BindingElement : BindingPattern Initializeropt
  1. value 设置为 ? GetV(value, propertyName)。
  2. 如果存在 Initializervalueundefined,则
    1. defaultValue 为 ? InitializerEvaluation
    2. value 设置为 ? GetValue(defaultValue)。
  3. 返回 ? 以 valueenvRecord 为实参执行 BindingPatternBindingInitialization
SingleNameBinding : BindingIdentifier Initializeropt
  1. bindingIdBindingIdentifierStringValue
  2. lhs 为 ? ResolveBinding(bindingId, envRecord)。
  3. value 设置为 ? GetV(value, propertyName)。
  4. 如果存在 Initializervalueundefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true,则
      1. value 设置为 ? 以 bindingId 为实参执行 InitializerNamedEvaluation
    2. 否则,
      1. defaultValue 为 ? InitializerEvaluation
      2. value 设置为 ? GetValue(defaultValue)。
  5. 如果 envRecordundefined,则返回 ? 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] ; Note

ExpressionStatement 不能以 U+007B (LEFT CURLY BRACKET) 开始,因为这可能使它与 Block 产生歧义。ExpressionStatement 不能以 functionclass 关键字开始,因为这会使它与 FunctionDeclarationGeneratorDeclarationClassDeclaration 产生歧义。ExpressionStatement 不能以 async function 开始,因为这会使它与 AsyncFunctionDeclarationAsyncGeneratorDeclaration 产生歧义。ExpressionStatement 不能以两个 token 序列 let [ 开始,因为这会使它与首个 LexicalBindingArrayBindingPatternlet LexicalDeclaration 产生歧义。

14.5.1 Runtime Semantics: Evaluation

ExpressionStatement : Expression ;
  1. exprRef 为 ? ExpressionEvaluation
  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] Note
前瞻限制 [lookahead ≠ else] 以通常方式解决经典的“悬挂 else”问题。也就是说,当关联哪个 if 的选择除此之外存在歧义时,else 会与候选 if 中最近的(最内层的)那个关联

14.6.1 Static Semantics: 早期错误

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

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

14.6.2 Runtime Semantics: Evaluation

IfStatement : if ( Expression ) Statement else Statement
  1. exprRef 为 ? ExpressionEvaluation
  2. exprValueToBoolean(? GetValue(exprRef))。
  3. 如果 exprValuetrue,则
    1. stmtCompletionCompletion(第一个 StatementEvaluation)。
  4. 否则,
    1. stmtCompletionCompletion(第二个 StatementEvaluation)。
  5. 返回 ? UpdateEmpty(stmtCompletion, undefined)。
IfStatement : if ( Expression ) Statement
  1. exprRef 为 ? ExpressionEvaluation
  2. exprValueToBoolean(? GetValue(exprRef))。
  3. 如果 exprValuefalse,则返回 undefined
  4. stmtCompletionCompletion(StatementEvaluation)。
  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 )

The abstract operation LoopContinues takes arguments completion (a Completion Record) and labelSet (a List of Strings) and returns a Boolean. It performs the following steps when called:

  1. 如果 completion 是 normal completion,则返回 true
  2. 如果 completion 不是 continue completion,则返回 false
  3. 如果 completion.[[Target]]empty,则返回 true
  4. 如果 labelSet 包含 completion.[[Target]],则返回 true
  5. 返回 false
Note

IterationStatementStatement 部分内,可以使用 ContinueStatement 来开始一次新的迭代。

14.7.1.2 Runtime Semantics: LoopEvaluation

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

IterationStatement : DoWhileStatement
  1. 返回 ? 以 labelSet 为实参执行 DoWhileStatementDoWhileLoopEvaluation
IterationStatement : WhileStatement
  1. 返回 ? 以 labelSet 为实参执行 WhileStatementWhileLoopEvaluation
IterationStatement : ForStatement
  1. 返回 ? 以 labelSet 为实参执行 ForStatementForLoopEvaluation
IterationStatement : ForInOfStatement
  1. 返回 ? 以 labelSet 为实参执行 ForInOfStatementForInOfLoopEvaluation

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 ) ; Note

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

14.7.2.2 Runtime Semantics: DoWhileLoopEvaluation

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

DoWhileStatement : do Statement while ( Expression ) ;
  1. iterationResultundefined
  2. 重复:
    1. stmtResultCompletion(StatementEvaluation)。
    2. 如果 LoopContinues(stmtResult, labelSet) 是 false,则返回 ? UpdateEmpty(stmtResult, iterationResult)。
    3. 如果 stmtResult.[[Value]] 不是 empty,则将 iterationResult 设置为 stmtResult.[[Value]]
    4. exprRef 为 ? ExpressionEvaluation
    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 Note

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

14.7.3.2 Runtime Semantics: WhileLoopEvaluation

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

WhileStatement : while ( Expression ) Statement
  1. iterationResultundefined
  2. 重复:
    1. exprRef 为 ? ExpressionEvaluation
    2. exprValue 为 ? GetValue(exprRef)。
    3. 如果 ToBoolean(exprValue) 是 false,则返回 iterationResult
    4. stmtResultCompletion(StatementEvaluation)。
    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 Note

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

ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

14.7.4.2 Runtime Semantics: ForLoopEvaluation

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

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. 如果存在第一个 Expression,则
    1. exprRef 为 ? 第一个 ExpressionEvaluation
    2. 执行 ? GetValue(exprRef)。
  2. 如果存在第二个 Expression,则令 test 为第二个 Expression;否则令 testempty
  3. 如果存在第三个 Expression,则令 increment 为第三个 Expression;否则令 incrementempty
  4. 返回 ? ForBodyEvaluation(test, increment, Statement, « », labelSet)。
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. 执行 ? VariableDeclarationListEvaluation
  2. 如果存在第一个 Expression,则令 test 为第一个 Expression;否则令 testempty
  3. 如果存在第二个 Expression,则令 increment 为第二个 Expression;否则令 incrementempty
  4. 返回 ? ForBodyEvaluation(test, increment, Statement, « », labelSet)。
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. oldEnv 为运行中执行上下文的 LexicalEnvironment。
  2. loopEnvNewDeclarativeEnvironment(oldEnv)。
  3. isConstLexicalDeclarationIsConstantDeclaration
  4. boundNamesLexicalDeclarationBoundNames
  5. boundNames 的每个元素 name,执行
    1. 如果 isConsttrue,则
      1. 执行 ! loopEnv.CreateImmutableBinding(name, true)。
    2. 否则,
      1. 执行 ! loopEnv.CreateMutableBinding(name, false)。
  6. 将运行中执行上下文的 LexicalEnvironment 设置为 loopEnv
  7. forDeclCompletion(LexicalDeclaration 的求值)。
  8. 如果 forDecl 是突兀完成,则
    1. forDecl 设置为 Completion(DisposeResources(loopEnv.[[DisposableResourceStack]], forDecl))。
    2. 断言:forDecl 是突兀完成。
    3. 将运行中执行上下文的 LexicalEnvironment 设置为 oldEnv
    4. 返回 ? forDecl
  9. 如果 isConstfalse,则令 perIterationLetsboundNames;否则令 perIterationLets 为一个新的空列表。
  10. 如果第一个 Expression 存在,则令 test 为第一个 Expression;否则令 testempty
  11. 如果第二个 Expression 存在,则令 increment 为第二个 Expression;否则令 incrementempty
  12. bodyResultCompletion(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 )

The abstract operation ForBodyEvaluation takes arguments test (an Expression Parse Node or empty), increment (an Expression Parse Node or empty), stmt (a Statement Parse Node), perIterationBindings (a List of Strings), and labelSet (a List of Strings) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. iterationResultundefined
  2. 执行 ? CreatePerIterationEnvironment(perIterationBindings)。
  3. 重复:
    1. 如果 test 不是 empty,则
      1. testRef 为 ? testEvaluation
      2. testValue 为 ? GetValue(testRef)。
      3. 如果 ToBoolean(testValue) 是 false,则返回 iterationResult
    2. resultCompletion(stmtEvaluation)。
    3. 如果 LoopContinues(result, labelSet) 是 false,则返回 ? UpdateEmpty(result, iterationResult)。
    4. 如果 result.[[Value]] 不是 empty,则将 iterationResult 设置为 result.[[Value]]
    5. 执行 ? CreatePerIterationEnvironment(perIterationBindings)。
    6. 如果 increment 不是 empty,则
      1. incRef 为 ? incrementEvaluation
      2. 执行 ? GetValue(incRef)。

14.7.4.4 CreatePerIterationEnvironment ( perIterationBindings )

The abstract operation CreatePerIterationEnvironment takes argument perIterationBindings (a List of Strings) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. 如果 perIterationBindings 有任何元素,则
    1. lastIterationEnv 为正在运行的执行上下文的 LexicalEnvironment。
    2. outerlastIterationEnv.[[OuterEnv]]
    3. 断言:outer 不是 null
    4. thisIterationEnvNewDeclarativeEnvironment(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-infor-offor-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] Note

本节由附录 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 Note

只有在实现了 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

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

MemberExpression : PrimaryExpression
  1. 如果 PrimaryExpressionObjectLiteralArrayLiteral,则返回 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. 返回 ForBindingIsDestructuring
ForBinding : BindingIdentifier
  1. 返回 false
ForBinding : BindingPattern
  1. 返回 true
Note

本节由附录 B.3.5 扩展。

14.7.5.3 Runtime Semantics: ForDeclarationBindingInitialization

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

ForDeclaration : LetOrConst ForBinding
  1. 返回 ? 以 valueenvRecord 为实参执行 ForBindingBindingInitialization
ForDeclaration : using ForBinding await using ForBinding
  1. 抛出 SyntaxError 异常。

14.7.5.4 Runtime Semantics: ForDeclarationBindingInstantiation

The syntax-directed operation ForDeclarationBindingInstantiation takes argument envRecord (a Declarative Environment Record) and returns unused. It is defined piecewise over the following productions:

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

14.7.5.5 Runtime Semantics: ForInOfLoopEvaluation

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

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(ForDeclarationBoundNames, 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(ForDeclarationBoundNames, 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(ForDeclarationBoundNames, AssignmentExpression, async-iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet, async)。
Note

本节由附录 B.3.5 扩展。

14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind )

The abstract operation ForIn/OfHeadEvaluation takes arguments uninitializedBoundNames (a List of Strings), expr (an Expression Parse Node or an AssignmentExpression Parse Node), and iterationKind (enumerate, iterate, or async-iterate) and returns either a normal completion containing an Iterator Record or an abrupt completion. It performs the following steps when called:

  1. oldEnv 为运行中的执行上下文的 LexicalEnvironment。
  2. 如果 uninitializedBoundNames 不是空的,则
    1. 断言:uninitializedBoundNames 没有重复项。
    2. newEnvNewDeclarativeEnvironment(oldEnv)。
    3. uninitializedBoundNames 的每个 String name,执行:
      1. 执行 ! newEnv.CreateMutableBinding(name, false)。
    4. 将运行中的执行上下文的 LexicalEnvironment 设置为 newEnv
  3. exprRefCompletion(exprEvaluation)。
  4. 将运行中的执行上下文的 LexicalEnvironment 设置为 oldEnv
  5. exprValue 为 ? GetValue(? exprRef)。
  6. 如果 iterationKindenumerate,则
    1. 如果 exprValueundefinednull,则
      1. 返回 Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }。
    2. obj 为 ! ToObject(exprValue)。
    3. iteratorEnumerateObjectProperties(obj)。
    4. nextMethod 为 ! GetV(iterator, "next")。
    5. 返回 Iterator Record { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }。
  7. 断言:iterationKinditerateasync-iterate
  8. 如果 iterationKindasync-iterate,则令 iteratorKindasync
  9. 否则,令 iteratorKindsync
  10. 返回 ? GetIterator(exprValue, iteratorKind)。

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

The abstract operation ForIn/OfBodyEvaluation takes arguments lhs (a Parse Node), stmt (a Statement Parse Node), iteratorRecord (an Iterator Record), iterationKind (enumerate or iterate), lhsKind (assignment, var-binding, or lexical-binding), and labelSet (a List of Strings) and optional argument iteratorKind (sync or async) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. 如果 iteratorKind 不存在,则将 iteratorKind 设置为 sync
  2. oldEnv 为运行中执行上下文的 LexicalEnvironment。
  3. iterationResultundefined
  4. 如果 lhsKindlexical-binding,则
    1. 断言:lhs 是一个 ForDeclaration
    2. 如果 lhsIsAwaitUsingDeclarationtrue,则
      1. declarationKindasync-dispose
    3. 否则如果 lhsIsUsingDeclarationtrue,则
      1. declarationKindsync-dispose
    4. 否则,
      1. declarationKindnormal
  5. 否则,
    1. declarationKindnormal
  6. destructuringlhsIsDestructuring
  7. 如果 destructuringtruelhsKindassignment,则
    1. 断言:lhs 是一个 LeftHandSideExpression
    2. assignmentPatternlhs覆盖的 AssignmentPattern
  8. 重复,
    1. nextResult 为 ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]])。
    2. 如果 iteratorKindasync,则将 nextResult 设置为 ? Await(nextResult)。
    3. 如果 nextResult 不是对象,则抛出 TypeError 异常。
    4. done 为 ? IteratorComplete(nextResult)。
    5. 如果 donetrue,则返回 iterationResult
    6. nextValue 为 ? IteratorValue(nextResult)。
    7. 如果 lhsKindassignmentvar-binding,则
      1. 如果 destructuringtrue,则
        1. 如果 lhsKindassignment,则
          1. status 为以 nextValue 为参数的 assignmentPatternDestructuringAssignmentEvaluationCompletion
        2. 否则,
          1. 断言:lhsKindvar-binding
          2. 断言:lhs 是一个 ForBinding
          3. status 为以 nextValueundefined 为参数的 lhsBindingInitializationCompletion
      2. 否则,
        1. lhsReflhs 的求值的 Completion。(它可能会被重复求值。)
        2. 如果 lhsKindassignmentlhsAssignmentTargetTypeweb-compat,则抛出 ReferenceError 异常。
        3. 如果 lhsRef 是突兀完成,则
          1. statuslhsRef
        4. 否则,
          1. statusCompletion(PutValue(lhsRef.[[Value]], nextValue))。
      3. iterationEnvundefined
    8. 否则,
      1. 断言:lhsKindlexical-binding
      2. 断言:lhs 是一个 ForDeclaration
      3. iterationEnvNewDeclarativeEnvironment(oldEnv)。
      4. 执行以 iterationEnv 为参数的 lhsForDeclarationBindingInstantiation
      5. 将运行中执行上下文的 LexicalEnvironment 设置为 iterationEnv
      6. 如果 destructuringtrue,则
        1. status 为以 nextValueiterationEnv 为参数的 lhsForDeclarationBindingInitializationCompletion
      7. 否则,
        1. 断言:lhs 绑定单个名称。
        2. lhsNamelhsBoundNames 的唯一元素。
        3. lhsRef 为 ! ResolveBinding(lhsName)。
        4. 如果 declarationKind 不是 normal,则
          1. 断言:IsUnresolvableReference(lhsRef) 是 false
          2. baselhsRef.[[Base]]
          3. 断言:base 是声明式环境记录。
          4. statusCompletion(AddDisposableResource(base.[[DisposableResourceStack]], nextValue, declarationKind))。
        5. 否则,
          1. statusNormalCompletion(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. 如果 iterationKindenumerate,则返回 ? status
      4. 断言:iterationKinditerate
      5. 如果 iteratorKindasync,则返回 ? AsyncIteratorClose(iteratorRecord, status)。
      6. 返回 ? IteratorClose(iteratorRecord, status)。
    10. resultstmt 的求值的 Completion
    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. 如果 iterationKindenumerate,则返回 ? status
      3. 断言:iterationKinditerate
      4. 如果 iteratorKindasync,则返回 ? 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. bindingIdBindingIdentifierStringValue
  2. 返回 ? ResolveBinding(bindingId)。

14.7.5.9 EnumerateObjectProperties ( obj )

The abstract operation EnumerateObjectProperties takes argument obj (an Object) and returns an iterator object. It performs the following steps when called:

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

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

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

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

  • obj 或其原型链中某个对象的 [[Prototype]] 内部槽的值发生变化,
  • obj 或其原型链中的某个对象移除了属性,
  • obj 的原型链中的某个对象添加了属性,或
  • obj 或其原型链中某个对象的某个属性的 [[Enumerable]] 特性值发生变化。
Note 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;
  }
}
Note 2
选择这些异质对象作为实现不要求匹配 CreateForInIterator 的对象列表,是因为实现历史上在这些情况中的行为有所不同,而在所有其他情况中行为一致。

14.7.5.10 For-In 迭代器对象

For-In Iterator 是一个表示对某个特定对象进行某次特定迭代的对象。For-In Iterator 对象永远不能被 ECMAScript 代码直接访问;它们的存在只是为了说明 EnumerateObjectProperties 的行为。

14.7.5.10.1 CreateForInIterator ( obj )

The abstract operation CreateForInIterator takes argument obj (an Object) and returns a For-In Iterator. 它用于创建一个 For-In Iterator 对象,该对象以特定顺序迭代 obj 的自有和继承的可枚举字符串属性。 It performs the following steps when called:

  1. iteratorOrdinaryObjectCreate(%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. iteratorthis 值。
  2. 断言:iterator 是 Object。
  3. 断言:iterator 具有 For-In Iterator 实例的所有内部槽(14.7.5.10.3)。
  4. objiterator.[[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. keyiterator.[[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. 如果 objnull,则返回 CreateIteratorResultObject(undefined, true)。

14.7.5.10.3 For-In Iterator 实例的属性

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

Table 34: For-In Iterator 实例的内部槽
内部槽 类型 描述
[[Object]] Object 其属性正被迭代的 Object 值。
[[ObjectWasVisited]] Boolean 如果迭代器已在 [[Object]] 上调用 [[OwnPropertyKeys]],则为 true;否则为 false
[[VisitedKeys]] Strings 的 List 此迭代器到目前为止已经发出的值。
[[RemainingKeys]] Strings 的 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. labelLabelIdentifierStringValue
  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. labelLabelIdentifierStringValue
  2. 返回 Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: label }。

14.10 return 语句

语法

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

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 为 ? ExpressionEvaluation
  2. exprValue 为 ? GetValue(exprRef)。
  3. 如果 GetGeneratorKind() 是 async,则将 exprValue 设置为 ? Await(exprValue)。
  4. 返回 ReturnCompletion(exprValue)。

14.11 with 语句

Note 1

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

语法

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

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

14.11.1 Static Semantics: 早期错误

WithStatement : with ( Expression ) Statement Note

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

14.11.2 Runtime Semantics: Evaluation

WithStatement : with ( Expression ) Statement
  1. value 为 ? ExpressionEvaluation
  2. obj 为 ? ToObject(? GetValue(value))。
  3. oldEnv 为运行中的执行上下文的 LexicalEnvironment。
  4. newEnvNewObjectEnvironment(obj, true, oldEnv)。
  5. 将运行中的执行上下文的 LexicalEnvironment 设置为 newEnv
  6. stmtCompletionCompletion(StatementEvaluation)。
  7. 将运行中的执行上下文的 LexicalEnvironment 设置为 oldEnv
  8. 返回 ? UpdateEmpty(stmtCompletion, undefined)。
Note

无论控制如何离开嵌入的 Statement,不管是正常离开、某种形式的 abrupt completion,还是异常,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

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

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

14.12.3 CaseClauseIsSelected ( caseClauseNode, input )

The abstract operation CaseClauseIsSelected takes arguments caseClauseNode (a CaseClause Parse Node) and input (an ECMAScript language value) and returns either a normal completion containing a Boolean or an abrupt completion. 它确定 caseClauseNode 是否匹配 input。 It performs the following steps when called:

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

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

14.12.4 Runtime Semantics: Evaluation

SwitchStatement : switch ( Expression ) CaseBlock
  1. exprRefExpression 的 ? Evaluation
  2. switchValue 为 ? GetValue(exprRef)。
  3. oldEnv 为运行中执行上下文的 LexicalEnvironment。
  4. blockEnvNewDeclarativeEnvironment(oldEnv)。
  5. 执行 BlockDeclarationInstantiation(CaseBlock, blockEnv)。
  6. 将运行中执行上下文的 LexicalEnvironment 设置为 blockEnv
  7. blockResult 为以 switchValue 为参数的 CaseBlockCaseBlockEvaluationCompletion
  8. 断言:blockEnv.[[DisposableResourceStack]] 是一个空列表。
  9. 将运行中执行上下文的 LexicalEnvironment 设置为 oldEnv
  10. 返回 blockResult
Note

无论控制如何离开 SwitchStatement,LexicalEnvironment 总会恢复到其先前状态。

CaseClause : case Expression :
  1. 返回 empty
CaseClause : case Expression : StatementList
  1. 返回 ? StatementListEvaluation
DefaultClause : default :
  1. 返回 empty
DefaultClause : default : StatementList
  1. 返回 ? StatementListEvaluation

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

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

14.13.1 Static Semantics: 早期错误

LabelledItem : FunctionDeclaration
  • 如果此产生式匹配到任何源文本,则为语法错误,除非该源文本是非严格代码,且宿主是 Web 浏览器或以其他方式支持 带标签的函数声明

14.13.2 Static Semantics: IsLabelledFunction ( stmt )

The abstract operation IsLabelledFunction takes argument stmt (a Statement Parse Node) and returns a Boolean. It performs the following steps when called:

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

14.13.3 Runtime Semantics: Evaluation

LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 ? 以 « » 为实参执行此 LabelledStatementLabelledEvaluation

14.13.4 Runtime Semantics: LabelledEvaluation

The syntax-directed operation LabelledEvaluation takes argument labelSet (a List of Strings) and returns either a normal completion containing either an ECMAScript language value or empty, or an abrupt completion. It is defined piecewise over the following productions:

BreakableStatement : IterationStatement
  1. stmtResultCompletion(以 labelSet 为实参执行 IterationStatementLoopEvaluation)。
  2. 如果 stmtResult 是 break completion,则
    1. 如果 stmtResult.[[Target]]empty,则
      1. 如果 stmtResult.[[Value]]empty,则将 stmtResult 设置为 NormalCompletion(undefined)。
      2. 否则,将 stmtResult 设置为 NormalCompletion(stmtResult.[[Value]])。
  3. 返回 ? stmtResult
BreakableStatement : SwitchStatement
  1. stmtResultCompletion(SwitchStatementEvaluation)。
  2. 如果 stmtResult 是 break completion,则
    1. 如果 stmtResult.[[Target]]empty,则
      1. 如果 stmtResult.[[Value]]empty,则将 stmtResult 设置为 NormalCompletion(undefined)。
      2. 否则,将 stmtResult 设置为 NormalCompletion(stmtResult.[[Value]])。
  3. 返回 ? stmtResult
Note 1

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

LabelledStatement : LabelIdentifier : LabelledItem
  1. labelLabelIdentifierStringValue
  2. newLabelSetlabelSet 和 « label » 的列表连接
  3. stmtResultCompletion(以 newLabelSet 为实参执行 LabelledItemLabelledEvaluation)。
  4. 如果 stmtResult 是 break completion 且 stmtResult.[[Target]]label,则
    1. stmtResult 设置为 NormalCompletion(stmtResult.[[Value]])。
  5. 返回 ? stmtResult
LabelledItem : FunctionDeclaration
  1. 返回 ? FunctionDeclarationEvaluation
Statement : BlockStatement VariableStatement EmptyStatement ExpressionStatement IfStatement ContinueStatement BreakStatement ReturnStatement WithStatement ThrowStatement TryStatement DebuggerStatement
  1. 返回 ? StatementEvaluation
Note 2

Statement 中仅有两个产生式对 LabelledEvaluation 具有特殊语义:BreakableStatementLabelledStatement

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 为 ? ExpressionEvaluation
  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] Note

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

14.15.1 Static Semantics: 早期错误

Catch : catch ( CatchParameter ) Block

14.15.2 Runtime Semantics: CatchClauseEvaluation

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

Catch : catch ( CatchParameter ) Block
  1. oldEnv 为运行中的执行上下文的 LexicalEnvironment。
  2. catchEnvNewDeclarativeEnvironment(oldEnv)。
  3. CatchParameterBoundNames 的每个元素 argName,执行:
    1. 执行 ! catchEnv.CreateMutableBinding(argName, false)。
  4. 将运行中的执行上下文的 LexicalEnvironment 设置为 catchEnv
  5. statusCompletion(以 thrownValuecatchEnv 为实参执行 CatchParameterBindingInitialization)。
  6. 如果 status 是 abrupt completion,则
    1. 将运行中的执行上下文的 LexicalEnvironment 设置为 oldEnv
    2. 返回 ? status
  7. blockCompletionCompletion(BlockEvaluation)。
  8. 将运行中的执行上下文的 LexicalEnvironment 设置为 oldEnv
  9. 返回 ? blockCompletion
Catch : catch Block
  1. 返回 ? BlockEvaluation
Note

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

14.15.3 Runtime Semantics: Evaluation

TryStatement : try Block Catch
  1. blockResultCompletion(BlockEvaluation)。
  2. 如果 blockResult 是 throw completion,则令 catchResultCompletion(以 blockResult.[[Value]] 为实参执行 CatchCatchClauseEvaluation)。
  3. 否则,令 catchResultblockResult
  4. 返回 ? UpdateEmpty(catchResult, undefined)。
TryStatement : try Block Finally
  1. blockResultCompletion(BlockEvaluation)。
  2. finallyResultCompletion(FinallyEvaluation)。
  3. 如果 finallyResult 是 normal completion,则将 finallyResult 设置为 blockResult
  4. 返回 ? UpdateEmpty(finallyResult, undefined)。
TryStatement : try Block Catch Finally
  1. blockResultCompletion(BlockEvaluation)。
  2. 如果 blockResult 是 throw completion,则令 catchResultCompletion(以 blockResult.[[Value]] 为实参执行 CatchCatchClauseEvaluation)。
  3. 否则,令 catchResultblockResult
  4. finallyResultCompletion(FinallyEvaluation)。
  5. 如果 finallyResult 是 normal completion,则将 finallyResult 设置为 catchResult
  6. 返回 ? UpdateEmpty(finallyResult, undefined)。

14.16 debugger 语句

语法

DebuggerStatement : debugger ;

14.16.1 Runtime Semantics: Evaluation

Note

求值 DebuggerStatement 时,在调试器下运行的实现可以因此产生一个断点。如果不存在调试器或调试器未激活,此语句没有可观察效果。

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