ECMAScript5学习笔记--第十二章 语句

语法:

Statement :

Block

VariableStatement

EmptyStatement

ExpressionStatement

IfStatement

IterationStatement

ContinueStatement

BreakStatement

ReturnStatement

WithStatement

LabelledStatement

SwitchStatement

ThrowStatement

TryStatement

DebuggerStatement

12.1  块

语法:Block :

   { StatementListopt }

   StatementList :

   Statement

   StatementList Statement

产生式Block:{}执行过程:

  

  1. 返回解释执行 StatementList 的结果。

 产生式 StatementList :Statement 按照下面的过程执行 :

  1. 令 s 为解释执行 Statement 的结果。
  2. 如果有一个异常被抛出,返回 (throw, V, empty),这里的 V 是异常。( 仿佛没有抛出异常一样继续运行。)
  3. 返回 s。

 产生式 StatementList :StatementList Statement 按照下面的过程执行 :

  1. 令 sl 为解释执行 StatementList 的结果。
  2. 如果 sl 是个非常规完结,返回 sl。
  3. 令 s 为解释执行 Statement 的结果。
  4. 如果有一个异常被抛出,返回 (throw, V, empty),这里的 V 是异常。 ( 仿佛没有抛出异常一样继续运行。)
  5. 如果 s.value 是 empty ,令 V = sl.value, 否则令 V = s.value。
  6. 返回 (s.type, V, s.target)。

12.2  变量语句

  当创建变量时初始化为 undefined。当 VariableStatement 被执行时变量关联的 Initialiser 会被分配 AssignmentExpression 的值,而不是在变量创建时。

12.3  空语句:

  EmptyStatement :

  ;

  返回(normal,empty,empty).

12.4  表达式语句

  ExpressionStatement :

  [lookahead ∉ {{, function}]Expression ;  

  1. 令 exprRef 为解释执行 Expression 的结果 .
  2. 返回 (normal, GetValue(exprRef), empty).

12.5  if语句

  IfStatement :

  if ( Expression ) Statement else Statement

  if ( Expression ) Statement

  产生式 IfStatement : if ( Expression ) Statement else Statement 按照下面的过程执行

  1. 令 exprRef 为解释执行 Expression 的结果 .
  2. 如果 ToBoolean(GetValue(exprRef)) is true ,then
    1. 返回解释执行 the 的结果 first Statement.
  3. Else,
    1. 返回解释执行 the 的结果 second Statement.

   产生式 IfStatement : if ( Expression ) Statement 按照下面的过程执行 :

  1. 令 exprRef 为解释执行 Expression 的结果 .
  2. 如果 ToBoolean(GetValue(exprRef)) is false ,return (normal, empty, empty).
  3. 返回解释执行 Statement 的结果 .

 12.6  迭代语句

  IterationStatement :

  do Statement while ( Expression );

  while ( Expression ) Statement

  for ( ExpressionNoInopt; Expressionopt ; Expressionopt ) Statement

  for ( var VariableDeclarationListNoIn; Expressionopt ; Expressionopt ) Statement

  for ( LeftHandSideExpression in Expression ) Statement

  for ( var VariableDeclarationNoIn in Expression ) Statement

12.6.1  do-while语句  

  1. 令 V = empty。
  2. 令 iterating 为 true。
  3. 只要 iterating 为 true,就重复
    1. 令 stmt 为解释执行 Statement 的结果。
    2. 如果 stmt.value 不是 empty,令 V = stmt.value。
    3. 如果 stmt.type 不是 continue || stmt.target 不在当前标签组,则
      1. 如果 stmt.type 是 break 并且 stmt.target 在当前标签组内,返回 (normal, V, empty)。
      2. 如果 stmt 是个 非常规完结 ,返回 stmt。
    4. 令 exprRef 为解释执行 Expression 的结果。
    5. 如果 ToBoolean(GetValue(exprRef)) 是 false,设定 iterating 为 false。
  4. 返回 (normal, V, empty);

12.6.2  while语句  

  1. 令 V = empty.
  2. 重复
    1. 令 exprRef 为解释执行 Expression 的结果 .
    2. 如果 ToBoolean(GetValue(exprRef)) 是 false,返回 (normal, V, empty).
    3. 令 stmt 为解释执行 Statement 的结果 .
    4. 如果 stmt.value 不是 empty,令 V = stmt.value.
    5. 如果 stmt.type 不是 continue || stmt.target 不在当前标签组内,则
      1. 如果 stmt.type 是 break 并且 stmt.target 在当前标签组内,则
        1. 返回 (normal, V, empty).
      2. 如果 stmt 是一个非常规完结,返回 stmt.

12.6.3  for语句

  1. 如果 ExpressionNoIn 是 present,则 .
    1. 令 exprRef 为解释执行 ExpressionNoIn 的结果 .
    2. 调用 GetValue(exprRef). ( 不会用到此值。)
  2. 令 V = empty.
  3. 重复
    1. 如果第一个 Expression 是 present,则
      1. 令 testExprRef 为解释执行第一个 Expression 的结果 .
      2. 如果 ToBoolean(GetValue(testExprRef)) 是 false,返回 (normal, V, empty).
    2. 令 stmt 为解释执行 Statement 的结果 .
    3. 如果 stmt.value 不是 empty,令 V = stmt.value
    4. 如果 stmt.type 是 break 并且 stmt.target 在当前标签组内,返回 (normal, V, empty).
    5. 如果 stmt.type 不是 continue || stmt.target 不在当前标签组内,则
      1. 如果 stmt 是个非常规完结,返回 stmt.
    6. 如果第二个 Expression 是 present,则
      1. 令 incExprRef 为解释执行第二个 Expression 的结果 .
      2. 调用 GetValue(incExprRef). ( 不会用到此值 .)

 产生式 IterationStatement : for ( var VariableDeclarationListNoIn ; Expressionopt ; Expressionopt ) Statement 按照下面的过程执行 :

  1. 解释执行 VariableDeclarationListNoIn.
  2. 令 V = empty.
  3. 重复
    1. 如果第一个 Expression 是 present,则
      1. 令 testExprRef 为解释执行第一个 Expression 的结果 .
      2. 如果 ToBoolean(GetValue(testExprRef)) 是 false,则返回 (normal, V, empty).
    2. 令 stmt 为解释执行 Statement 的结果 .
    3. 如果 stmt.value 不是 empty,令 V = stmt.value.
    4. 如果 stmt.type 是 break 并且 stmt.target 在当前标签组内,返回 (normal, V, empty).
    5. 如果 stmt.type 不是 continue || stmt.target 不在当前标签组内,则
      1. 如果 stmt 是个非常规完结,返回 stmt.
    6. 如果第二个 Expression 是 present,则 .
      1. 令 incExprRef 为解释执行第二个 Expression 的结果 .
      2. 调用 GetValue(incExprRef). ( 不会用到此值 .)

12.6.4  for-in语句

 产生式 IterationStatement : for ( LeftHandSideExpression in Expression ) Statement 按照下面的过程执行 :

  1. 令 exprRef 为解释执行 Expression 的结果 .
  2. 令 experValue 为 GetValue(exprRef).
  3. 如果 experValue 是 null 或 undefined,返回 (normal, empty, empty).
  4. 令 obj 为 ToObject(experValue).
  5. 令 V = empty.
  6. 重复
    1. 令 P 为 obj 的下一个 [[Enumerable]] 特性为 true 的属性的名。如果不存在这样的属性,返回 (normal, V, empty).
    2. 令 lhsRef 为解释执行 LeftHandSideExpression 的结果 ( 它可能解释执行多次 ).
    3. 调用 PutValue(lhsRef, P).
    4. 令 stmt 为解释执行 Statement 的结果 .
    5. 如果 stmt.value 不是 empty,令 V = stmt.value.
    6. 如果 stmt.type 是 break 并且 stmt.target 在当前标签组内,返回 (normal, V, empty).
    7. 如果 stmt.type 不是 continue || stmt.target 不在当前标签组内,则
      1. 如果 stmt 是非常规完结,返回 stmt.

 产生式 IterationStatement : for ( var VariableDeclarationNoIn in Expression ) Statement 按照下面的过程执行 :

  1. 令 varName 为解释执行 VariableDeclarationNoIn 的结果 .
  2. 令 exprRef 为解释执行 Expression 的结果 .
  3. 令 experValue 为 GetValue(exprRef).
  4. 如果 experValue 是 null 或 undefined,返回 (normal, empty, empty).
  5. 令 obj 为 ToObject(experValue).
  6. 令 V = empty.
  7. 重复
    1. 令 P 为 obj 的下一个 [[Enumerable]] 特性为 true 的属性的名。如果不存在这样的属性,返回 (normal, V, empty).
    2. 令 varRef 为解释执行 varName 的结果,仿佛它是个标示符引用 (11.1.2); 它可能解释执行多次 .
    3. 调用 PutValue(varRef, P).
    4. 令 stmt 为解释执行 Statement 的结果 .
    5. 如果 stmt.value 不是 empty,令 V = stmt.value.
    6. 如果 stmt.type 是 break 并且 stmt.target 在当前标签组内,返回 (normal, V, empty).
    7. 如果 stmt.type 不是 continue || stmt.target 不在当前标签组内,则
      1. 如果 stmt 是非常规完结,返回 stmt.

    枚举的属性 ( 第一个算法中的步骤 6.a,第二个算法中的步骤 7.a) 的机制和顺序并没有指定。在枚举过程中枚举的对象属性可能被删除。如果在枚举过程中,删除了还没有被访问到的属性,那么它将不会被访问到。如果在枚举过程中添加新属性到列举的对象,新增加的属性也无法保证被当前执行中的枚举访问到。在任何枚举中对同一个属性名称的访问不得超过一次。

     枚举一个对象的属性包括枚举其原型的属性,还有原型的原型,等等,递归;但是如果原型的一个属性是shadowed那么不会枚举这个属性,因为原型链中之前某个对象有同名的属性了。当一个原型对象的一个属性是在原型链中之前对象的shadowed,那么在决定是否枚举时不需要考虑 [[Enumerable]] 特性的值。

12.7  continue语句

  ContinueStatement :

  continue ;

  continue [ 此处无换行 ] Identifier ;

 如果以下任意一个为真,那么程序被认为是语法错误的:

  • 程序包含一个不带可选的 Identifier 的 break 语句,没有直接或间接 ( 不跨越函数边界 ) 的嵌套在 IterationStatement 或 SwitchStatement 里。
  • 程序包含一个有可选的 Identifier 的 break 语句,这个 Identifier 没有出现在 Statement 中闭合标签组里 ( 不跨越函数边界 )。

 一个没有 Identifier 的 BreakStatement 按照下面的过程执行 :

  1. 返回 (continue, empty, empty).

 一个有可选的 Identifier 的 BreakStatement 按照下面的过程执行 :

  1. 返回 (continue, empty, Identifier).

12.9  return语句

  语法:

  ReturnStatement :

  return ;

  return [ 此处无换行 ] Expression ;  

   在一个 ECMAScript 程序中包含的 return 语句没有在 FunctionBody 里面,那么就是语法错误的。一个 return 语句导致函数停止执行,并返回一个值给调用者。如果省略Expression,返回值是 undefined。否则,返回值是 Expression 的值。

   产生式 ReturnStatement :' return' [no LineTerminator here] Expressionopt ; 按照下面的过程执行 :

  1. 如果 Expression 不是 present,返回 (return, undefined, empty).
  2. 令 exprRef 为解释执行 Expression 的结果 .
  3. 返回 (return, GetValue(exprRef), empty).

12.10  with语句

  语法:

  WithStatement :

  with ( Expression ) Statement

  with 语句为计算对象给当前执行环境的 词法环境 添加一个对象 环境记录项 。然后,用这个增强的 词法环境 执行一个语句。最后,恢复到原来的 词法环境 。

  产生式 WithStatement : with ( Expression ) Statement 按照下面的过程执行 :

  1. 令 val 为解释执行 Expression 的结果 .
  2. 令 obj 为 ToObject(GetValue(val)).
  3. 令 oldEnv 为运行中的执行环境的 LexicalEnvironment.
  4. 令 newEnv 为以 obj 和 oldEnv 为参数调用 NewObjectEnvironment 的结果。
  5. 设定 newEnv 的 provideThis 标志为 true。
  6. 设定运行中的执行环境的 LexicalEnvironment 为 newEnv.
  7. 令 C 为解释执行 Statement 的结果,但如果解释执行是由异常抛出,则令 C 为 (throw, V, empty),这里的 V 是异常。( 现在继续执行,仿佛没有抛出异常。)
  8. 设定运行中的执行环境的 LexicalEnvironment 为 oldEnv.
  9. 返回 C.

   无论控制是从嵌入的 Statement 怎样离开的,不论是正常离开还是以 非常规完结 或异常,LexicalEnvironment 总是恢复到它之前的状态。严格模式不能包含with语句

12.11  switch语句

  语法:

  SwitchStatement :

  switch ( Expression )

  CaseBlock CaseBlock :

  { CaseClausesopt }

  { CaseClausesoptDefaultClause CaseClausesopt }

  CaseClauses :

  CaseClause

  CaseClauses CaseClause

  CaseClause :

  case Expression : StatementListopt

  DefaultClause :

  default : StatementListopt

   产生式 SwitchStatement : switch ( Expression ) CaseBlock 按照下面的过程执行 :

  1. 令 exprRef 为解释执行 Expression 的结果 .
  2. 令 R 为以 GetValue(exprRef) 作为参数解释执行 CaseBlock 的结果。
  3. 如果 R.type 是 break 并且 R.target 在当前标签组内,返回 (normal, R.value, empty).
  4. 返回 R.

   产生式 CaseBlock : { CaseClausesopt } 以一个给定输入参数 input, 按照下面的过程执行 :

  1. 令 V = empty.
  2. 令 A 为以源代码中顺序排列的 CaseClause 列表。
  3. 令 searching 为 true.
  4. 只要 searching 为 true,就重复
    1. 令 C 为 A 里的下一个 CaseClause。 如果没有 CaseClause 了,返回 (normal, V, empty).
    2. 令 clauseSelector 为解释执行 C 的结果 .
    3. 如果 input 和 clauseSelector 是 === 操作符定义的相等,则
      1. 设定 searching 为 false.
      2. 如果 C 有一个 StatementList, 则
        1. 令 R 为解释执行 C 的 StatementList 的结果。
        2. 如果 R 是个非常规完结 , 则返回 R。
        3. 令 V =R.value
  5. 重复
    1. 令 C 为 A 里的下一个 CaseClause。 如果没有 CaseClause 了,返回 (normal, V, empty).
    2. 如果 C 有一个 StatementList, 则
      1. 令 R 为解释执行 C 的 StatementList 的结果。
      2. 如果 R.value 不是 empty, 则令 V =R.value.
      3. 如果 R 是个非常规完结 , 则返回 (R.type,V,R.target).

 产生式 CaseBlock : { CaseClausesoptDefaultClause CaseClausesopt } 以一个给定输入参数 input, 按照下面的过程执行 :

  1. 令 V = empty.
  2. 令 A 为第一个 CaseClauses 中以源代码中顺序排列的 CaseClause 列表。
  3. 令 B 为第二个 CaseClauses 中以源代码中顺序排列的 CaseClause 列表。
  4. 令 found 为 false.
  5. 重复,使 C 为 A 中的依次每个 CaseClause。
    1. 如果 found 是 false,则
      1. 令 clauseSelector 为解释执行 C 的结果 .
      2. 如果 input 和 clauseSelector 是 === 操作符定义的相等,则设定 found 为 true.
    2. 如果 found 是 true,则
      1. 如果 C 有一个 StatementList,则
        1. 令 R 为解释执行 C 的 StatementList 的结果。
        2. 如果 R.value 不是 empty, 则令 V =R.value.
        3. R 是个非常规完结 , 则返回 (R.type,V,R.target).
  6. 令 foundInB 为 false.
  7. 如果 found 是 false,则
    1. 只要 foundInB 为 false 并且所有 B 中的元素都没有被处理,就重复
      1. 令 C 为 B 里的下一个 CaseClause.
      2. 令 clauseSelector 为解释执行 C 的结果 .
      3. 如果 input 和 clauseSelector 是 === 操作符定义的相等,则
        1. 设定 foundInB 为 true.
        2. 如果 C 有一个 StatementList, 则
          1. 令 R 为解释执行 C 的 StatementList 的结果。
          2. 如果 R.value 不是 empty, 则令 V =R.value.
          3. R 是个非常规完结 , 则返回 (R.type,V,R.target).
  8. 如果 foundInB 是 false 并且 DefaultClause 有个 StatementList, 则
    1. 令 R 为解释执行 DefaultClause 的 StatementList 的结果 .
    2. 如果 R.value 不是 empty, 则令 V = R.value.
    3. 如果 R 是个非常规完结 , 则返回 (R.type, V, R.target).
  9. 重复 ( 注 : 如果已执行步骤 7.a.i, 此循环不从 B 的开头开始。)
    1. 令 C 为 B 的下一个 CaseClause。如果没有 CaseClause 了 , 返回 (normal, V, empty).
    2. 如果 C 有个 StatementList, 则
      1. 令 R 为解释执行 C 的 StatementList 的结果。
      2. 如果 R.value 不是 empty, 则令 V = R.value.
      3. 如果 R 是个非常规完结 , 则返回 (R.type, V, R.target).

 产生式 CaseClause : case Expression : StatementListopt 按照下面的过程执行 :

  1. 令 exprRef 为解释执行 Expression 的结果 .
  2. 返回 GetValue(exprRef).

  

12.12  标签语句

  语法:

  LabelledStatement :

  Identifier : Statement

   一个 Statement 可以由一个标签作为前缀。标签语句仅与标签化的 break 和 continue 语句一起使用。ECMAScript 没有 goto 语句。

   如果一个 ECMAScript 程序包含有相同 Identifier 作为标签的 LabelledStatement 闭合的 LabelledStatement,那么认为它是是语法错误的 。这不适用于直接或间接嵌套在标签语句里面的 FunctionDeclaration 的 body 里出现标签的情况。

   产生式 Identifier : Statement 的解释执行方式是,先添加 Identifier 到 Statement 的标签组,再解释执行 Statement。如果 LabelledStatement 自身有一个非空标签组,这些标签还是会添加到解释执行前的 Statement 的标签组里。如果 Statement 的解释执行结果是 (break, V, L),这里的 L 等于 Identifier,则产生式的结果是 (normal, V, empty)。

   在解释执行 LabelledStatement 之前,认为包含的 Statement 拥有一个空标签组,除非它是 IterationStatement 或 SwitchStatement,这种情况下认为它拥有一个包含单个元素 empty 的标签组。

12.13  throw语句

  语法:

  ThrowStatement :

  throw [no LineTerminator here] Expression ; 

  1. 令 exprRef 为解释执行 Expression 的结果 .
  2. 返回 (throw, GetValue(exprRef), empty).

12.14  try语句

  语法:

  TryStatement :

  try Block Catch

  try Block Finally

  try Block Catch Finally

  Catch :

  catch ( Identifier )

  Block Finally :

  finally Block

   try 语句包裹一个可以出现特殊状况,如果运行时错误或 throw 语句的代码块。catch 子句提供了异常处理代码。如果 catch 子句捕获到一个异常,这个异常会绑定到它的 Identifier 上。

   语义:

   产生式 TryStatement : try Block Catch 按照下面的过程执行 :

  1. 令 B 为解释执行 Block 的结果 .
  2. 如果 B.type 不是 throw,返回 B.
  3. 返回一参数 B 解释执行 Catch 的结果 .

   产生式 TryStatement : try Block Finally 按照下面的过程执行 :

  1. 令 B 为解释执行 Block 的结果 .
  2. 令 F 为解释执行 Finally 的结果 .
  3. 如果 F.type 是 normal,返回 B.
  4. 返回 F.

   产生式 TryStatement : try Block Catch Finally 按照下面的过程执行 :

  1. 令 B 为解释执行 Block 的结果 .
  2. 如果 B.type 是 throw,则
    1. 令 C 为以参数 B 解释执行 Catch 的结果 .
  3. 否则 , B.type 不是 throw,
    1. 令 C 为 B.
  4. 令 F 为解释执行 Finally 的结果 .
  5. 如果 F.type 是 normal,返回 C.
  6. 返回 F.

   产生式 Catch : catch ( Identifier ) Block 按照下面的过程执行 :

  1. 令 C 为传给这个产生式的参数 .
  2. 令 oldEnv 为运行中执行环境的 LexicalEnvironment.
  3. 令 catchEnv 为以 oldEnv 为参数调用 NewDeclarativeEnvironment 的结果
  4. 以 Identifier 字符串值为参数调用 catchEnv 的 CreateMutableBinding 具体方法。
  5. 以 Identifier, C, false 为参数调用 catchEnv 的 SetMutableBinding 具体方法。注:这种情况下最后一个参数无关紧要。
  6. 设定运行中执行环境的 LexicalEnvironment 为 catchEnv.
  7. 令 B 为解释执行 Block 的结果 .
  8. 设定运行中执行环境的 LexicalEnvironment 为 oldEnv.
  9. 返回 B.

   不管控制是怎样退出 Block 的,LexicalEnvironment 总是会恢复到其之前的状态。

   产生式 Finally : finally Block 按照下面的过程执行 :

  1. 返回解释执行 Block 的结果 .

12.15  debugger语句

  语法:

  DebuggerStatement :

  debugger ;  

  解释执行 DebuggerStatement 产生式可允许让一个实现在调试器下运行时设置断点。如果调试器不存在或是非激活状态,这个语句没有可观测效果。

   产生式 DebuggerStatement : debugger ; 按照下面的过程执行 :

  1. 如果一个实现定义了可用的调试工具并且是开启的,则
    1. 执行实现定义的调试动作。
    2. 令 result 为实现定义的 Completion 值 .
  2. 否则
    1. 令 result 为 (normal, empty, empty).
  3. 返回 result.
原文地址:https://www.cnblogs.com/Decmber/p/5785096.html