Skip to content

关于要不要写分号 #16

@K-Kevin

Description

@K-Kevin

ref:《重学前端》

我们写代码要不要写分号?

自动插入分号规则

  • 要有换行符,且下一个符号是不符合语法的,那么就尝试插入分号。
  • 有换行符,且语法中规定此处不能有换行符,那么就自动插入分号。
  • 源代码结束处,不能形成完整的脚本或者模块结构,那么就自动插入分号。
let a = 1
void function(a){
    console.log(a);
}(a);

第一行后有换行符,接下来 void 跟在 1 之后是不合法的,所以第一条规则符合插入换行符;

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

第二行 a 之后有换行符,后面有 ++ 运算符,a 后面跟着 ++ 是合法的,按理说插入换行符,ab 为 2,c 等于 1,但是实际上结果却是 bc 为 2,a 是 1,因为下面提到的[no LineTerminator here]

UpdateExpression[Yield, Await]:
    LeftHandSideExpression[?Yield, ?Await]
    LeftHandSideExpression[?Yield, ?Await][no LineTerminator here]++
    LeftHandSideExpression[?Yield, ?Await][no LineTerminator here]--
    ++UnaryExpression[?Yield, ?Await]
    --UnaryExpression[?Yield, ?Await]
(function(a){
    console.log(a);
})()
(function(a){
    console.log(a);
})()

上面是两个 IIFE 立即执行函数表达式,我们看第三行 () 结束,js 引擎认为函数返回的可能是个函数,那么后面再跟上括号则形成了函数的调用,那么也是合理的,所以也应该换行符,但是实际上这么运行是会报错的。所以在 IIFE 函数时必须再行首加分号的原因就是因此。

function f(){
    return/*
        This is a return value.
    */1;
}
f();

在这 return 和 1 被注释分开了。根据 JavaScript 自动插入分号规则,带换行符的注释也被认为是有换行符,return 同样也有 [no LineTerminator here] 规则要求。所以这里 return 后会自动插入分号,返回是 undefined。

no LineTerminator here 规则

[no LineTerminator here] 规则表示它所在的结构中的这一位置不能插入换行符。

下图列出了所有标准中的规则。
image

所以上面 ++ -- 后自增和后自减运算符为什么插入换行符就知道为什么了。

不写分号需要注意的情况

以括号开头的
(function(a){
    console.log(a);
})()/* 这里没有被自动插入分号 */
(function(a){
    console.log(a);
})()

所以 IIFE 函数要注意。

以数组开头的语句
var a = [[]]/* 这里没有被自动插入分号 */
[3, 2, 1, 0].forEach(e => console.log(e))

这段代码本意是一个变量 a 赋值,然后对一个数组执行forEach,但是因为没有自动插入分号,被理解为下标运算符和逗号表达式,不会抛出错误。

以正则表达式开头的语句
var x = 1, g = {test:()=>0}, b = 1/* 这里没有被自动插入分号 */
/(a)/g.test("abc")
console.log(RegExp.$1)

正则的第一个斜杠被理解成了除号,后面的意思就都变了

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions