Javascript分号,加仍是不加?

本文同步自个人博客园:http://hustskyking.cnblogs.com函数

关于这个问题,网上已经有不少人讨论过了,我先说说本身对这个问题的回答:加!(但非必须)spa

有些人写代码,懒得加分号,除非是无可奈何才勉强放一个分号上去。若是你能够保证你写的代码不出现任何 bug,那固然是没有问题,可是不少 JSer 新人,对一些隐含的问题并非特别清楚,很容易在不知不觉中写出一堆 bug,咱们先来了解下 JS 词法语法解析的时候,哪些状况下会自动插入分号。翻译

1、自动插入分号的规则

1. 程序从左到右解析,当归入下一个 token 没法匹配任何语法: rest

  • 如该 token 跟以前的 token 之间有至少一个 LineTerminal 行终结符违反分割
  • 该 token 为 `}` 符号时

2. 程序从左到右解析,当归入下一个(或几个) token 不能产生一条合法的语句的时候,会在这个地方插入一个分号。code

3. 程序从左到右解析,当归入的 token 可以产生一条合法语句,可是这条语句是受限产生式时,在该受限 token 前面自动插入分号。blog

上面提到的一些内容来自 ECMAScript5.1 第七章第九节,能够戳这里,翻译的不太通顺,实在是太难翻译了= =token

2、一些不加分号会出问题的场景

场景一:ip

s = a + b
(x + y).doSomething()

咱们指望这是这是两条语句,结果会被解析成:terminal

s = a + b(x + y).doSomething();

b 在这里成了一个函数了。get

场景二:

x
++
y

这个 ++ 符号会给谁?答案是:

x; ++y;

这样的代码固然是不多遇到,可是遇到这种状况:

场景三:

return 
true

咱们指望返回 true,结果:

return;
true;

给咱们返回了 undefined。

场景四:

s = function(x){return x}
(1 + 2).toString()

他被解析成了

s = function(x){return x}(1 + 2).toString()

function(x){return x}(1 + 2) 这个做为一个总体,1+2 做为参数送入函数,该函数的返回值为 3,而后执行 3.toString(),这样的问题藏的比较深,不容易被发现。

3、规避问题

有些语句是以 [ 或者 ( 开头,就想上面提到的场景一和场景四,这些 token 很容易和上一条没有加分号的语句合并到一块儿,若是你不太喜欢加分号,能够这样来处理:

s = function(x){return x}
;(1 + 2).toString()

这也是为何咱们会常常看到别人的代码中写出这样的函数:

;(function(){
    // ...
})();

在 function 的前面加了一个分号,目的就是为了防止整个函数的返回值做为参数送入上一条语句之中。

对于场景三,要特别说明一下,除了 return 以外,还有 break 和 continue 语句,break 和 continue 相似 C 语言中的 goto ,他是能够在后面添加 tag 的,若是 tag 和 这些关键词之间存在 LineTerminal ,这些 tag 就会被忽略,如:

break
tag

咱们指望程序会调到 tag 所指向的程序段,但结果被解析成

break;
tag;

4、小结

看到上面的一些列问题,相信你们内心仍是有本身的答案了,若是你有信心代码里头不出现由于不写分号而致使的错误,那分号的取舍实际上是无所谓的。

相关文章
相关标签/搜索