Javascript分号,加还是不加?

简介:

关于这个问题,网上已经有很多人讨论过了,我先说说自己对这个问题的回答:加!(但非必须)

有些人写代码,懒得加分号,除非是迫不得已才勉强放一个分号上去。如果你可以保证你写的代码不出现任何 bug,那当然是没有问题,但是很多 JSer 新人,对一些隐含的问题并不是特别清楚,很容易在不知不觉中写出一堆 bug,我们先来了解下 JS 词法语法解析的时候,哪些情况下会自动插入分号。

一、自动插入分号的规则

注:鼠标滑过文字可以看到翻译原文

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

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

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

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

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

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

场景一:

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

我们期望这是这是两条语句,结果会被解析成:

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

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

场景二:

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(),这样的问题藏的比较深,不容易被发现。

三、规避问题

有些语句是以 [ 或者 ( 开头,就像上面提到的场景一和场景四,这些 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;

四、小结

看到上面的一些列问题,相信大家心里还是有自己的答案了,如果你有信心代码里头不出现因为不写分号而导致的错误,那分号的取舍其实是无所谓的。






本文转自Barret Lee博客园博客,原文链接:http://www.cnblogs.com/hustskyking/p/semicolon-retalk.html,如需转载请自行联系原作者

目录
相关文章
|
JavaScript
node.js 分号问题
node.js 分号问题
102 0
|
前端开发 JavaScript
重学前端 29 # JavaScript中要不要加分号?
重学前端 29 # JavaScript中要不要加分号?
78 0
重学前端 29 # JavaScript中要不要加分号?
|
JavaScript 前端开发
JavaScript 代码结构:语句、分号和注释
JavaScript 代码结构:语句、分号和注释
141 0
JavaScript 代码结构:语句、分号和注释
|
JavaScript 前端开发
[翻译] 国外大神的js 分号使用指南
• Required: When two statements are on the same line 必备: 当两个语句在同一行时 var i = 0; i++ // <-- semicolon obligatory // (but optional before newline) var i = 0 // <-- semicolon optional i++ // <-- semicolon optional • Optional: After statement
90 0
|
JavaScript 前端开发 开发者
JavaScript ASI 机制详解,不用再纠结分号问题
关于要不要加分号的问题,其实有很多争论!有的坚持加分号,而有的不喜欢加分号...但是无论那种风格,都不能百分百避免某些特殊情况产生的问题,究其根本就是因为对 JavaScript 解析和 ASI 规则的不了解。
287 0
|
JavaScript 前端开发
JavaScript ECMAScript规范里对于分号semicolon用法最权威的定义
JavaScript ECMAScript规范里对于分号semicolon用法最权威的定义
121 0
JavaScript ECMAScript规范里对于分号semicolon用法最权威的定义
|
JavaScript 前端开发
JavaScript ECMAScript规范里对于分号semicolon用法最权威的定义
JavaScript ECMAScript规范里对于分号semicolon用法最权威的定义
133 0
JavaScript ECMAScript规范里对于分号semicolon用法最权威的定义
|
JavaScript 前端开发
JS的分号可以省掉吗?
写不写分号,这是个有趣的问题....
1350 0
|
JavaScript 前端开发 Java
不为人知的JavaScript自动分号插入机制( ASI )
JavaScript拥有自由的精神, ASI就是此精神的表现形式之一, ASI是Automatic semicolon insertion 的缩写, 在许多语句后面可以省略分号, 当然很多小白还没有发现这一点... ASI的引入方便了开发者的同时也带来了很多坑........ 本文介绍了自动插入分号机制在return语句中的例子,以及在es5标准下的相应规则。
2373 0
|
JavaScript 前端开发 安全
JS编程建议——5:防止JavaScript自动插入分号
5:防止JavaScript自动插入分号
1190 0