美文网首页
06丨到底要不要写分号呢?

06丨到底要不要写分号呢?

作者: littleyu | 来源:发表于2019-06-05 12:01 被阅读0次

自动插入分号规则

自动插入分号规则其实独立于所有的语法产生式定义,它的规则说起来非常简单,只有三条。

  • 要有换行符,且下一个符号是不符合语法的,那么就尝试插入分号。
  • 有换行符,且语法中规定此处不能有换行符,那么就自动插入分号。
  • 源代码结束处,不能形成完整的脚本或者模块结构,那么就自动插入分号。

举两个例子🌰:

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

在这个例子中,第一行的结尾处有换行符,接下来 void 关键字接在 1 之后是不合法的,这命中了我们的第一条规则,因此会在 void 前插入换行符。

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

也是个著名的例子,我们看第二行的 a 之后,有换行符,后面遇到了 ++ 运算符,a 后面跟 ++ 是合法的语法,但是后面跟着 b 就是不合法的,本该插入分号,但是下文 no LineTerminator here 又规定后自增前不能有换行符,于是,这里 a 的后面就要插入一个分号了。所以这段代码最终的结果,bc 都变成了 2,而 a 还是 1

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

这个例子是比较有实际价值的例子,这里两个 function 调用的写法被称作 IIFE(立即执行的函数表达式),是个常见技巧。

这段代码意图上显然是形成两个 IIFE

我们来看第三行结束的位置,JavaScript 引擎会认为函数返回的可能是个函数,那么,在后面再跟括号形成函数调用就是合理的,因此这里不会自动插入分号。

这是一些鼓励不写分号的编码风格会要求大家写 IIFE 时必须在行首加分号的原

ps: no LineTerminator here 规则

好了,到这里我们已经讲清楚了分号自动插入的规则,但是我们要想彻底掌握分号的奥秘,就必须要对 JavaScript 的语法定义做一些数据挖掘工作。

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

自动插入分号规则的第二条:有换行符,且语法中规定此处不能有换行符,那么就自动插入分号。跟 no LineTerminator here 规则强相关,那么我们就找出 JavaScript 语法定义中的这些规则。

敲重点!!

不写分号需要注意的情况

下面我们来看几种不写分号容易造成错误的情况,你可以稍微注意一下,避免发生同样的问题。

1.以括号开头的语句

我们在前面的案例中,已经展示了一种情况,那就是以括号开头的语句:

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

这段代码看似两个独立执行的函数表达式,但是其实第三组括号被理解为传参,导致抛出错误。

2.以数组开头的语句

除了括号,以数组开头的语句也十分危险:

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

这段代码本意是一个变量 a 赋值,然后对一个数组执行 forEach,但是因为没有自动插入分号,被理解为下标运算符和逗号表达式,我这个例子展示的情况,甚至不会抛出错误,这对于代码排查问题是个噩梦。

3.以正则表达式开头的语句

正则表达式开头的语句也值得你去多注意一下。我们来看这个例子。

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

这段代码本意是声明三个变量,然后测试一个字符串中是否含有字母 a,但是因为没有自动插入分号,正则的第一个斜杠被理解成了除号,后面的意思就都变了。

注意,我构造的这个例子跟上面的例子一样,同样不会抛错,凡是这一类情况,都非常致命。

Template 开头的语句
Template 开头的语句比较少见,但是跟正则配合时,仍然不是不可能出现:

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

这段代码本意是声明函数 f,然后赋值给 g,再测试 Template 中是否含有字母 a。但是因为没有自动插入分号,函数 f 被认为跟 Template 一体的,进而被莫名其妙地执行了一次。

相关文章

  • 06丨到底要不要写分号呢?

    自动插入分号规则 自动插入分号规则其实独立于所有的语法产生式定义,它的规则说起来非常简单,只有三条。 要有换行符,...

  • js 必须要加分号的场景

    一行开头是括号或者方括号的时候,末尾必须要加分号。以下代码会报错: 这种情况要加分号: 至于js 到底要不要写分号...

  • 论假期和代码

    假期到底要不要写代码 假期到底要不要写代码 假期到底要不要写代码 还是写吧。。。 还是看会儿手机吧。。 在看部电影...

  • js不加分号党进来,我来教你做人

    前言 js语句末尾到底要不要加分号,早已形成了加分号党和不加分号党,而且吵得不可开交,各有各的道理,但是,你们都没...

  • 要不要写呢?

    简书牛,励志,写作,习惯,深度,高度

  • 到底要写什么呢…

    第一次接触这个啊,要说什么呢…让我想想…

  • 自己刚学Swift的理解.

    >1.swift句尾不要分号.除非一行要写多行代码加分号隔开 >2.swift不要写main函数.程序默认从上往下...

  • 锁到没脾气

    在考虑以后到底还要不要写日常了。

  • 写简历时,到底要不要写年龄呢?

    ​建议简历中基本的个人信息要完整。 HR看简历的时候,主要通过两点判断是否可以通过筛选: 一, 基础条件是否具备 ...

  • 单身汪的情人节

    提笔时不由在想今天可是情人节哦,要不要出去遛遛狗什么,到底要不要写呢,不过看到这你已经知道我的结果是什么了,...

网友评论

      本文标题:06丨到底要不要写分号呢?

      本文链接:https://www.haomeiwen.com/subject/dmpjxctx.html