首页 > 为什么 Bootstrap 的 js 源码不写分号?

为什么 Bootstrap 的 js 源码不写分号?

看了很多 Bootstrap 源码,发现每句话都不加分号,这样写有什么特殊意义么?随便贴一段:

Tab.prototype.show = function () {
    var $this    = this.element
    var $ul      = $this.closest('ul:not(.dropdown-menu)')
    var selector = $this.attr('data-target')
    if (!selector) {
        selector = $this.attr('href')
        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
    }
    if ($this.parent('li').hasClass('active')) return
    var previous = $ul.find('.active:last a')[0]
    var e        = $.Event('show.bs.tab', {
        relatedTarget: previous
    })
    $this.trigger(e)
    if (e.isDefaultPrevented()) return
    var $target = $(selector)
    this.activate($this.parent('li'), $ul)
    this.activate($target, $target.parent(), function () {
        $this.trigger({
        type: 'shown.bs.tab'
        , relatedTarget: previous
        })
    })
}

  1. 加不加分号是个人偏好问题。但是如果你的团队要求加分号,你就加吧。鉴于从 C/C++/Java/C# 转来做前端的开发人员这么多,而不加分号对他们来说无异于用脚写代码,所以你就随着他们吧。
  2. 我正在逐渐不加分号,但是出现一个问题:

// a.js (function(){ console.log('a.js') })() // b.js (function(){ console.log('b.js') })()

这两个 JS 单独运行没问题,但是合并之后就会报错:

undefined is not a function

我只能在 concat 的时候在文件末尾添加一个分号。当然你也可以把它们改写为


// a.js void (function(){ console.log('a.js') })() // b.js void (function(){ console.log('b.js') })()

写了两年coffeescript,整个10+人的团队也都是写coffeescript,分号是什么?


js 本身就具备这种功能 可以加 可以不加的


js语法本身是需要使用分号来结束语句的。但js解释器具备 分号自动插入(Automatic Semicolon Insertion) 的能力。这大概是 JavaScript 里最受争议的特性之一吧。
据说js的作者被C等语言弄烦了,所以就给js增加了这一特性,允许你在js代码的某些部分省略分号,而在解释器层面自动加入。
由于js的分号自动插入规则是面向解析器、从语法解析的角度(通过js代码文本逆推出语法树的过程)去定义的,所以我们从常规理解js代码角度(根据js语法编写代码)去看会发现其规则非常纠结,展开讲会很头疼(以我的表述能力来说)于是我不多废话了。

简单的就其一般形式而言,语句结束后换行,或者直接闭合代码块(比如函数代码体的结束}符号),就能激活分号自动插入特性。

在实际应用中,加不加分号以个人爱好而定。我个人是基于“既然js规范定义了分号自动插入特性那么我就使用吧”这一脑洞想法成为了不加分号党。当然也是希望通过这些细节在具体代码编写加深自己对js基础的巩固,毕竟我是非专业的。

但需要注意的是,某些不完善的js压缩、合并、混淆工具可能无法正确地应对这一特性,在处理代码时会破坏分号自动插入的条件,也不具备主动插入分号的能力,从而导致生成的代码报错。

如果会遇到上述问题并不知道如何解决的话,还是建议优先采取手动插入分号的形式。
当然也有不少折中的写法,就是在代码块的最后一句省略分号,但其它位置都手动添加分号,比如如下形式:

function a() {
    var b = 1;
    alert(b)
}

如果是单个库文件,那么写不写分号都行。
但是如果启用压缩,而没有分号,那就是悲剧了。
如果你想把多个库文件合并成为一个,而没有分号,那也是悲剧的开始。
如果你的代码是使用自动化工具编译生成的,那么有没有分号都行,反正修改以后很容易编译。


JavaScript不加分号,浏览器也能正常执行的。(不过一般而言压缩的时候会自动加分号的。例如google closure和uglify.js都能自动加分号。)

缩进良好,可读性也不差。

当然边边角角可能会有些小问题,留心一下即可。


有些人认为没分号看着舒服,有些人反倒是觉得没分号感觉怪怪的。其实加不加分号全在个人习惯。其次就是团队的代码规范。一切取决于实际情况。


  1. 在没有jslint之类的编辑器中书写js代码, 你不写分号, 编辑器并不会提示你这个问题, 试想一下, 如果你坚持加分号这个风格, 茫茫代码中, 即使你漏了一个分号你都不会发现, C还好, 即使书写的不能发现, 编译时也肯定能发现, 然而js却可以正常运行, 如果你不使用对分号有要求的压缩工具或者jslint的话, 这个漏掉的分号你如何去发现? 别人在读你代码的时候, 突然发现有一个地方没有分号, 那么他是否会困惑于这个漏掉的分号是真的漏掉还是有意为之?

  2. 有一个想法就是, 如果不书写分号, 那么在压缩js的时候, 压缩工具无法正常压缩, 这也是很多坚持写分号的同仁所在乎的, 但是, 直觉上来说, js解释器能读懂的, 觉得没错的, 为什么压缩工具却不行呢? 只能说, 压缩工具的实现不够优秀, 让很多人, 为了写分号而写分号, 这是一种讨好行为, 这种行为是否可取呢? 取决于你的编程态度: 选择讨好人类但不讨好机器的风格, 还是选择讨好机器但不讨好人类的风格?

  3. 团队习惯吧, 如果项目发起人习惯不加分号, 而且'加不加分号'这个问题也不是什么原则性问题, 后来者继续遵循着这个习惯也是很自然的

  4. 如果写分号了, 那么你也可以为所欲为的脏写代码了, 两三句代码放一行的毛病就会容易犯, 如果不写分号, 代码书写上也会避免这个毛病, 当然, 如果你说你没有这个毛病, 那么, 你不觉得每行后面都跟着一个分号很多余么?

没什么结论, 不写分号挺好


JavaScript不加分号,也没错。
加,或者不加,这是一个问题。
墙裂建议加分号。


关于分号问题的详解,请看这个知乎问题的答案:http://www.zhihu.com/question/20298345

我个人已经不写分号一年多了,代码看着舒爽。但这主要还是个人偏好。

【热门文章】
【热门文章】