关于JavaScript语句后面的分号问题

JavaScript自动加分号规则,有3条

  1. 当有换行符(包括含有换行符的多行注释),并且下一个token没法跟前面的语法匹配时,会自动补分号。
  2. 当有}时,如果缺少分号,会补分号
  3. 当程序源代码结束时,如果缺少分号,会补分号。 

利用我自己的JS语法分析工具JSinJS(https://github.com/kissjs/JSinJS ),我求出了所有能够出现在语句第一个的JS语法标记 (就是Statement的first集合),他们是:

["debugger", "try", "throw", "switch", "Identifier", "with", "return", "break", "continue", "for", "while", "do", "if", "new", "function", "(", "{", "[", "RegularExpressionLiteral", "StringLiteral", "NumericLiteral", "BooleanLiteral", "NullLiteral", "this", "!", "~", "-", "+", "--", "++", "typeof", "void", "delete", ";", "var"]

共计35个。 

我又求出了所有可以出现在分号之前的语法标记(即去掉分号以后的last集),他们是

["--", "++", "IdentifierName", "]", ")", "}", "RegularExpressionLiteral", "StringLiteral", "NumericLiteral", "BooleanLiteral", "NullLiteral", "Identifier", "this", "debugger", "return", "break", "continue"]

共计17个。

35*17 = 595种组合,为了方便记忆,以下我分组来讨论语法歧义 。(本来用Excel弄了张表,不过表太大了不好贴出来)

首先,以下语法标记开头的语句是绝对安全的,不会跟不加分号的上一行产生任何歧义:

var if do while for continue break return with switch throw try debugger ;

接下来我们来分组看不加分号导致的语法歧义:

  1. 第一种是++和--两种运算符出现在上一行结尾的情况,下一行以以下开头时,会产生语法歧义: 
  2. function delete void typeof new null true false NumericLiteral StringLiteral RegularExpressionLiteral ( [ { Identifier ++ -- + - ~ ! 
  3. 其中,function和delete是非常常用的statement开头。
  4. 特别是 ++和--单独被断为一行的时候,因为JS的语法规则规定后自增运算不允许中间插入换行,所以++和--会被视为前自增而跟下一行连接在一起。
  5. 第二种是return作为上一行结尾的情况,下一行以以下开头时,会产生语法歧义:
  6. function delete void typeof ( [ { Identifier ++ -- + - ~ !
  7. 同样因为JS语法的规则不允许在return 和后面的值之间插入换行,所以return之后只要有换行符就会视为有分号,这常常会与使用者的期望不符合。
  8. 第三种是下一行以+和-开头的情况,上一行以以下结尾是,会产生语法歧义:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/983.html