没有浏览器/ implentation具体,但Section 7.9 Automatic Semicolon Insertion
在的ECMAScript语言规范是值得一读。
7.9 自动分号插入
某些 ECMAScript 语句(空语句、变量语句、表达式语句、do-while 语句、continue 语句、break 语句、return 语句和 throw 语句)必须以分号终止。此类分号可能始终明确出现在源文本中。但是,为方便起见,在某些情况下,源文本中可能会省略此类分号。这些情况的描述是说在这些情况下分号会自动插入到源代码令牌流中。
7.9.1 自动分号插入规则 分号插入有三个基本规则:
当程序从左到右解析时,遇到任何语法产生式都不允许的记号(称为违规记号),如果出现以下一项或多项情况,则会在违规记号前自动插入分号条件为真:
- 至少有一个 LineTerminator 将违规令牌与前一个令牌分开。
- 违规令牌是}。
当程序从左到右解析时,遇到令牌输入流的末尾并且解析器无法将输入令牌流解析为单个完整的 ECMAScript 程序时,则自动在末尾插入分号输入流。
当程序从左到右解析时,遇到语法的某些产生式允许的标记,但该产生式是受限产生式并且该标记将是紧跟注释之后的终结符或非终结符的第一个标记?[这里没有 LineTerminator]?在受限制的产生式中(因此这样的标记称为受限制的标记),并且受限制的标记与前一个标记至少通过一个 LineTerminator 分隔,然后在受限制的标记之前自动插入分号。但是,前面的规则有一个额外的覆盖条件:如果分号随后将被解析为空语句,或者该分号将成为 for 语句标头中的两个分号之一,则永远不会自动插入分号(请参阅12.6.3)。注意以下是语法中唯一受限制的产生式: PostfixExpression : LeftHandSideExpression [此处没有 LineTerminator] ++ LeftHandSideExpression [此处没有 LineTerminator] -- ContinueStatement : continue [此处没有 LineTerminator] Identifier ; BreakStatement : break [此处没有 LineTerminator] 标识符;ReturnStatement : return [此处没有 LineTerminator] 表达式;ThrowStatement : throw [这里没有 LineTerminator] 表达式;这些受限产生式的实际效果如下:当遇到 ++ 或 -- 标记时解析器会将其视为后缀运算符,并且在前面的标记和 ++ 或 -- 标记之间至少出现一个 LineTerminator , 然后在 ++ 或 -- 标记之前自动插入一个分号。当继续、中断、返回时,或 throw 标记并且在下一个标记之前遇到 LineTerminator,在 continue、break、return 或 throw 标记之后自动插入分号。对 ECMAScript 程序员的实用建议是: 后缀 ++ 或 -- 运算符应与其操作数出现在同一行。return 或 throw 语句中的表达式应该与 return 或 throw 标记在同一行开始。break 或 continue 语句中的标识符应与 break 或 continue 标记在同一行。return 或 throw 语句中的表达式应该与 return 或 throw 标记在同一行开始。break 或 continue 语句中的标识符应与 break 或 continue 标记在同一行。return 或 throw 语句中的表达式应该与 return 或 throw 标记在同一行开始。break 或 continue 语句中的标识符应与 break 或 continue 标记在同一行。
7.9.2 自动分号插入示例
来源
{ 1 2 } 3
不是 ECMAScript 语法中的有效句子,即使有自动分号插入规则。相比之下,源
{ 1
2 } 3
也不是有效的 ECMAScript 语句,而是通过自动分号插入转换为以下内容:
{ 1
;2 ;} 3;
这是一个有效的 ECMAScript 语句。来源
for (a; b
)
不是有效的 ECMAScript 语句,并且不会被自动分号插入更改,因为 for 语句的标题需要分号。自动分号插入永远不会在 for 语句的标题中插入两个分号之一。来源
return
a + b
通过自动分号插入转换为以下内容:
return;
a + b;
注意表达式 a + b 不被视为返回语句返回的值,因为 LineTerminator 将它与标记返回分开。来源
a = b
++c
通过自动分号插入转换为以下内容:
a = b;
++c;
注意 标记 ++ 不被视为应用于变量 b 的后缀运算符,因为 LineTerminator 出现在 b 和 ++ 之间。来源
if (a > b)
else c = d
不是有效的 ECMAScript 语句,并且不会被 else 标记之前的自动分号插入更改,即使此时不适用语法的产生式,因为自动插入的分号随后将被解析为空语句。来源
a = b + c
(d + e).print()
不会通过自动分号插入进行转换,因为第二行开始的括号表达式可以解释为函数调用的参数列表:
a = b + c(d + e).print()
在赋值语句必须以左括号开头的情况下,程序员最好在前面的语句末尾提供一个明确的分号,而不是依赖于自动插入分号。