我在大学里的第一节C语言课上老师告诉我,不写分号的代码就是垃圾代码,我看都不会看。
于是我从那天起就养成了凡是代码必写分号的习惯,甚至变成了这样 ↓
大概有一天我在网上看了一个人的jQuery教程,他不书写分号的代码书写方式让我颇为难受(强迫症),甚至就算他讲的非常生动,我还是关掉了他的视频。
直到有一天我碰到了ESlint,写分号报错???我开始疑惑了,到底代码的后面该不该加分号呢?
先让我们了解一下自动插入分号规则。
自动插入分号规则
自动插入分号规则不属于任何语言,是独立的规则。
规则1:换行符后的第一个字符不合法,则插入分号
规则2:规则中不能有换行符的位置出现换行符,则插入分号
规则3:结束位置且不能形成完整的模块或脚本的,则插入分号
规则非常的简单易懂也就不过多说了,但是当出现另外一个规则的时候,问题就变得复杂了起来,那就是no LineTerminator here
no LineTerminator here
no LineTerminator here是JavaScript中的规则,它表示该处在它所在的结构中不能插入换行符,这就和自动插入分号规则中的规则2联系了起来。
规则1:不能在带标签的continue语句后添加换行符
规则2:不能再带标签的break语句后添加换行符
规则3:return后不能添加换行符
规则4:后置++,后置--的前面不能添加换行符
规则5:throw和Exception之间不能添加换行符
规则6:async后面不能插入换行符
规则7:箭头函数的箭头前不能添加换行符
规则8:yield的后面不能添加换行符
下面看一个例子:
当解读到第一个++的时候,由于前面有a,为后置++,则会触发no LineTerminator here的规则4,所以会在a的后面添加分号,这样一来就变成了++b和++c,所以结果就会变成a还是1,而b和c就都变成了2
结果如上
这二者的结合看上去会让不写分号时的代码也能顺利运行,但是!就像typepf null一样,这个规则是有bug的。所以遇到下面这些情况的时候你需要格外的注意。
情况1:以括号开头的语句
当两个IIFE(立即执行函数)连续写在一起的时候,第三行结束后,后面的括号会被解释为传参,并不会在第三行后添加分号,这样一来便会抛出错误。
情况2:以数组开头的语句
这段代码被理解为下标运算符和逗号表达式,更恐怖的是,它还不报错。
情况3:以正则表达式开头的语句
由于声明的最后面没有自动添加分号,导致正则表达式的第一个符号被理解为除号
情况4:以Template开头的语句
函数f被认为是和Template是一体的,进而莫名其妙的就被执行了一次。
看过这些之后,相信在该不该写分号,以及什么时候必须写分号都有所了解。