返回顶部

OutOfMemory.CN技术专栏-> javascript-> JavaScript语句末尾应该加分号么?

JavaScript语句末尾应该加分号么?

更多

关于JavaScript中行尾分号问题, 由来争议已久.

其中有大师Douglas Crockford以及JSLint的建议一定添加方位分号, 也有很多其他大牛(诸如Zepto的作者)加入了 无分号党 .

其中孰是孰非也是仁者见仁, 智者见智了.

这篇文章下面会为大家介绍 无分号党 中代表人物"Mislav Marohnić"对于此问题的阐述.

JavaScript是一门脚本语言, 它的代码段结束符是可选的.

但是, 总是有一群人在质疑这个特性, 这也导致了, 大部分开发人员都会 推荐总是包含分号 , "仅仅为了安全".

安全从何而来? 我一直在搜寻开发人员强制添加分号的原因. 下面是我找到的一些原因.


规范含义很模糊并且JavaScript实现存在差异

分号自动插入的规则 , 但是要有一个很明确的理解有些困难的.

至于JavaScript的实现中关于这些规则的差异, 好吧, 我还没有找到过.

当我向开发人员咨询或查找讨论资料时, 通常他们的回答都是"浏览器确实崩溃过, 但是我忘了具体情况", 当然, 他们从未记起过.

我总是编写"无分号代码", 按照我的经验, 没有发现任何一个JavaScript解释器不能处理这些代码.


没有分号, 无法压缩JavaScript 代码

缩减JavaScript源码文件大小包括三种级别: 压缩(例如gzip), 简化(比如去除不必要的空格及注释), 混淆(改变代码, 缩短变量和函数名).

压缩(Compression)是最简单的, 只需要一次性的服务端配置, 而不需要开发人员额外的工作以及无需代码. 有一段时间IE6是不能处理这种方式的, 但是如果我记得没错, 多年前已经打了补丁并推送了Windows更新, 如今已经没人在意这点了.

简化(Minification)与混淆(Obfuscation)会改变代码. 有很多的工具都标榜着"对于JavaScript文件, 尝试把它们变的更小, 但不会影响功能性". 对于这些工具, 我是有些抵触的, 因为如果不使用特定的代码格式, 比如添加分号, 它们就会破坏我的代码. 对于社区强制要求特定代码格式的要求, 其实我是ok的, 但不包括这些工具的要求.

设想一段在所有目标JavaScript实现(主流浏览器及一些服务端实现)中可用的代码, 如果压缩工具破坏了我的这段代码, 我会很忧桑的认为那是工具本身是错的. 如果工具编辑了JavaScript代码, 那么它最好像一个真正的解释器来理解代码.

对于压缩这一话题, 让我们做一个显示的检查. 我获取了 jQuery 的源码并 去除了所有的分号 , 然后在代码上运行 Google Closure Compiler . 结果文件大小为 76,673字节 . 而 jquery.min.js 的大小为 76,674字节 , 仅仅多了一个字节. 正如所见, 几乎没有任何变化, 当然, 测试用例也像之前一样通过了.

为什么会这样? 好吧, 考虑以下代码:

var a=1
var b=2
var c=3

这段代码大小为24个字节. 标记上分号, 运行压缩器:

var a=1;var b=2;var c=3;

依然是24个字节. 因此, 添加分号并去除换行符没有节省任何空间. 大多数节省的空间不是通过删除换行符体现的 - 而是通过删除代码注释和行首缩进实现的.

更新:很多人指出他们的压缩器重写了表达式, 比如 var a=1,b=2,c=3 . 我知道一些工具会这样处理, 但是此部分的观点只是探寻分号与空格的关系. 如果压缩器有着优秀的表达式重写能力(比如:闭包编译器), 那么意味着它也可以自动插入分号.

还有一些人推荐强制在代码块外使用花括号, 即使只有一行代码:

// before
if(condition) stuff()

// after
if(condition){
    stuff()
}

// after minification
if(condition){stuff()}

即使压缩后, 强制添加花括号也会至少增加一个字节的空间开销. 我不确定这有什么好处 - 对于空间及可读性都没有任何益处.

下面列举出了一些其他空格敏感的语言:

当然, 服务器端代码没有必要进行压缩. 为以下论点我做了这个列表: 空格可以并且总是可以, 部分(标记)语言. 这并不是一件坏事.


优秀的编码习惯

还听到过如下观点:

这是另一种表达"其他人都这么做"的方式, 也常常被在线讨论时理屈词穷的人们用到.

对于 JSLint 我的建议是: 不要使用它. 为什么要使用它? 如果你深信它会帮助你减少代码中的BUG, 有这样一个观点: 只有能发现并解决软件BUG的人, 没有那样的工具. 因此将工具丢到一边, 让更多的人来阅读你的代码吧.

Douglas Crockford说过"使用4个空格缩进", 然而大多数流行的JavaScript库都被设置为 tabs 2个空格 . 社区内的不同项目也是存在差异的, 它们就应该是那样. 正如我之前所说: 让人们和你本身形成你的代码风格, 而不是个人或某个工具.

你或许注意到在这篇文章中, 我并没有告诉你们应该坚持"无空格". 我只是阐述了可以这么做的具体证据. 但是选择权还在你们那.

对于代码风格, 它们的存在是为了提升开发人员对于代码的可读性与易理解性. 请深入思考是否分号提示了你代码的可读性. 对于可读性提示最大的因素应该是:空格缩进, 分隔代码块的空行, 拉长表达式的空格, 以及良好的变量及方法的命名方式. 阅读一些混淆过的代码, 其中包含了分号. 但这对于可读性有任何帮助么? 没有, 而恰恰是大量的空格与最初的变量名起到了真正的作用.


分号插入在返回代码内被吞了

当我搜索"JavaScript semicolon insertion"时, 最多的描述是这样的:

function add() {
    var a = 1, b = 2
    return
    a + b
}

当你绞尽脑汁想明白为什么他们要把 return 代码另起一行时, 我们可以继续来看这段代码是如何解析的:

return;
a + b;

唉, 这个函数没有返回我们需要的"和"! 但是你猜怎么着? 这个问题不是靠在 return 表达式末尾添加一个分号(也就是, a+b后面)来解决的, 而是通过删除 return 后面的换行符解决的:

return a + b

这样的内容真的是很离谱, 这些人建议他们的读者通过添加分号来避免这样的问题. 呃, 好吧, 只是帮助不到到这个特定的例子而已. 我们只需要更好的理解这门语言是如何解析的.


唯一真正的缺陷

这是"无分号"情况下唯一需要注意的地方:

// careful: will break
a = b + c
(d + e).print()

这段代码会被执行为:

a = b + c(d + e).print();

这个例子是取自于 JavaScript 2.0 功能兼容性 , 但我也在自己的程序中使用这个模型模式运行了若干次.

简单的解决方案: 当一行以圆括号开始时, 给它预置一个分号.

;(d + e).print()

这可能不是很优雅, 但是起到了作用. Michaeljohn Clement甚至研究的更加深入 :

如果选择在可能的地方忽视分号, 我的建议是: 在任何代码块中, 只要以开括号( ( , [] )或任意数学运算符(+ - * /)开头, 在符号之前应立即插入一个分号.

将这条建议视为一个规则, 你会受益良多.

注:本文为译文,原文出处 Semicolons in JavaScript are optional

推荐阅读:
支持

0

反对

0

感谢本文作者Clark To Do!

您可以通过下面的社交媒体联系/了解作者的更多信息:

发表评论