Javascript分号,加还是不加?

Posted 北方的刀郎

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;

    四、小结

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

以上是关于Javascript分号,加还是不加?的主要内容,如果未能解决你的问题,请参考以下文章

Javascript分号,加还是不加?

Javascript分号,加还是不加?

为什么函数声明后可以不加分号而函数表达式后要加分号呢?

js不加分号的代码风格应该注意的问题

为啥onclick=""引号中放置的方法后面有时候加;有时候不加啊

JavaScript 分号使用总结