资讯专栏INFORMATION COLUMN

细说 Javascript 拾遗篇(三) : 自动插入分号

mushang / 1718人阅读

摘要:此时会自动插入分号,解析器将再次尝试。工作原理下面的代码没有分号,因此解析器将会自己判断在哪些地方插入分号。前置小括号在有前置小括号的情形时,解析器将不会自动插入分号。这不仅将保证代码整体的一致性,也将有效地避免解析器对代码行为的错误改变。

尽管 Javascript 有类似 C 的句法风格,但是它并不强制在代码中使用分号,所以分号可能被省略。
Javascript 并不是一个缺少分号的语言,实际上,它需要分号来解析代码。因此当 Javascript 解析器遇到缺少分号而导致错误时会自动插入分号。

var foo = function() {
} // parse error, semicolon expected
test()

此时 Javascript 会自动插入分号,解析器将再次尝试。

var foo = function() {
}; // no error, parser continues
test()

自动的分号插入被认为是 Javascript 设计的缺陷之一,因为它能改变代码的行为。

工作原理

下面的代码没有分号,因此 Javascript 解析器将会自己判断在哪些地方插入分号。

(function(window, undefined) {
    function test(options) {
        log("testing!")

        (options.list || []).forEach(function(i) {

        })

        options.value.test(
            "long string to pass here",
            "and another long string to pass"
        )

        return
        {
            foo: function() {}
        }
    }
    window.test = test

})(window)

(function(window) {
    window.someLibrary = {}

})(window)

下面是解析器自行猜想后的结果:

(function(window, undefined) {
    function test(options) {

        // Not inserted, lines got merged
        log("testing!")(options.list || []).forEach(function(i) {

        }); // <- inserted

        options.value.test(
            "long string to pass here",
            "and another long string to pass"
        ); // <- inserted

        return; // <- inserted, breaks the return statement
        { // treated as a block

            // a label and a single expression statement
            foo: function() {} 
        }; // <- inserted
    }
    window.test = test; // <- inserted

// The lines got merged again
})(window)(function(window) {
    window.someLibrary = {}; // <- inserted

})(window); //<- inserted

很明显,解析器插入分号后已经改变了代码原本的行为。

前置小括号

在有前置小括号的情形时,解析器将不会自动插入分号 。

log("testing!")
(options.list || []).forEach(function(i) {})

代码将被解析器转换为一行:

log("testing!")(options.list || []).forEach(function(i) {})
总结

基于以上研究,强烈建议在书写 Javascript 代码的时候不要省略分号,同时也建议大括号应该与对应的表达式处于同一行,即使 if else 语句只有一句也尽量不要省略大括号。这不仅将保证代码整体的一致性,也将有效地避免 Javascript 解析器对代码行为的错误改变。

对于是否省略 Javascript 分号,@barretlee 有篇博文写的很好,尤其是其中的一些例子举得很有代表性:

  

《Javascript分号,加还是不加?》

JavaScript Garden 接下来一章节介绍 delete 操作符,由于之前我自己已经研究过 delete 相关机制 - 《Javascript - Delete 机制》。因此我不打算再重复总结一篇博文。

参考

http://bonsaiden.github.io/JavaScript-Garden/#core.semicolon

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78116.html

相关文章

  • 细说 Javascript 遗篇(二) : undefined 和 null

    摘要:有两个可以表示空的值,分别是和,比较有作用的是前者。访问声明但未初始化的变量。有返回值时函数的表达式没有显式的返回任何内容。然而,为了比较其他变量和值,我们需要提前取得的值。因此,从标准实行后,全局变量已经是不再可写。 Javascript 有两个可以表示空的值,分别是 undefined 和 null,比较有作用的是前者。 undefined undefined 是一种值为 un...

    My_Oh_My 评论0 收藏0
  • 细说 Javascript 遗篇(一) : 远离 eval 函数

    摘要:然而,函数只有在当前作用域中直接被调用并且被调用的函数名为才会被执行。在全局作用域下,这个字符串会一直被执行,在这个情形下我们并没有直接调用函数,也可以执行字符串。总结函数应该尽可能地避免使用。 Javascript 的 eval 函数可以在当前作用域执行一段包含 Javascript 代码的字符串。 var foo = 1; function test() { var fo...

    imtianx 评论0 收藏0
  • 细说 Javascript 遗篇(四) : setTimeout 和 setInterval

    摘要:当间隔时间设置较小时,将会导致回调函数堆积。处理可能阻塞的代码最简单且最可控的方式就是在回调函数内部使用函数。但是很明显,由于指定最大值的限制,还会有定时器没有被清除掉。另外,尽量避免使用函数,从而避免可能导致的回调函数堆积现象。 由于 Javascript 是异步的,因此我们可以通过 setTimeout 和 setInterval 函数来指定特定时间执行代码。 function ...

    wangjuntytl 评论0 收藏0
  • JavaScript ASI 机制详解

    摘要:最近在清理的未读列表,看到了才知道了的,一种自动插入分号的机制。这种行为被叫做自动插入分号,简称。不过在省略分号的风格中,这种解析特性会导致一些意外情况。规则标准定义的包括三条规则和两条例外。规则一情况三就是为量身定做的。 TL;DR 最近在清理 Pocket 的未读列表,看到了 An Open Letter to JavaScript Leaders Regarding Semico...

    frontoldman 评论0 收藏0
  • Javascript分号,加还是不加?

    摘要:本文同步自我的博客园关于这个问题,网上已经有很多人讨论过了,我先说说自己对这个问题的回答加但非必须有些人写代码,懒得加分号,除非是迫不得已才勉强放一个分号上去。 本文同步自我的博客园:http://hustskyking.cnblogs.com 关于这个问题,网上已经有很多人讨论过了,我先说说自己对这个问题的回答:加!(但非必须) 有些人写代码,懒得加分号,除非是迫不得已才勉强放一...

    Coding01 评论0 收藏0

发表评论

0条评论

mushang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<