Netherspite

JavaScript中的分号

自动插入分号的规则

  1. 有换行符,且下一个符号是不符合语法的,就尝试插入分号

    let a = 1
    void function(a) {
    console.log(a);
    }(a);

    此处第一行结尾有换行符,接下来的void关键字在1之后是不合法的,会在void前插入换行符。

  2. 有换行符,且语法中规定此处不能有换行符,那么自动插入分号

    var a = 1, b = 1, c = 1;
    a
    ++
    b
    ++
    c

    a之后又换行符,遇到了++运算符,是合法的语法,但是++运算符在语法中规定不能有换行符,于是在a后面插入分号,最终++与b相连处理,最后结果是a为1,b和c为2。

  3. 源代码结束处,不能形成完整的脚本或者模块结构,就自动插入分号

No LineTerminator here规则

在自动插入分号规则的第二条中,语法规定不能有换行符,与No LineTerminator here规则相关。不能插入换行的位置如下:

  • 带标签的continue/break语句
  • return
  • 后自增、后自减运算符
  • throw和Exception之间
  • async关键字后
  • 箭头函数的箭头前
  • yield关键字后

不写分号的注意点

以括号开头的语句

这段代码是想实现两个IIFE,但第三行结束的地方可能返回一个函数,后面紧跟着的括号形成函数调用是合理的,因此这里不会自动插入分号,因此才有在IIFE在行首加分号的代码。

(function(a){ 
console.log(a);
})()
(function(a){
console.log(a);
})()

以数组开头的语句

第二行会被理解为下标运算符和逗号表达式,而且不会抛出错误。

var a = [[]]/* 这里没有被自动插入分号 */
[3, 2, 1, 0].forEach(e => console.log(e))

以正则表达式开头的语句

第二行开头的/会被理解为除号,后面的意思都变了,也同样不会抛出错误。

var x = 1, g = {test:()=>0}, b = 1
/* 这里没有被自动插入分号 */
/(a)/g.test("abc")
console.log(RegExp.$1)

以Template开头的语句

函数f会被理解为与Template一体从而执行一次

var f = function(){ 
return "";
}
var g = f/* 这里没有被自动插入分号 */
`Template`.match(/(a)/);
console.log(RegExp.$1)

 评论