以下代码说明了分配的对象文字,但之后没有分号:
var literal = { say: function(msg) { alert(msg); } } literal.say("hello world!");
这似乎是合法的,并且不会发出警告(至少在Firefox 3中).这是完全合法的,还是有严格的JavaScript版本,这是不允许的?
我特别想知道未来的兼容性问题...我想写"正确的"JavaScript,所以如果技术上我需要使用分号,我想使用它.
从技术上讲,JavaScript在许多情况下都有分号作为可选项.
但是,作为一般规则,在任何声明的最后使用它们.为什么?因为如果您想要压缩脚本,它将为您节省无数个小时的挫败感.
自动分号插入由解释器执行,因此如果您愿意,可以将它们留出.在评论中,有人声称
分号对于break/continue/throw等语句不是可选的
但这是不正确的.它们是可选的; 真正发生的是线路终结器影响自动分号插入; 这是一个微妙的差异.
这是分号插入标准的其余部分:
然而,为方便起见,在某些情况下可以从源文本中省略这样的分号.这些情况通过说在这些情况下分号自动插入源代码令牌流来描述.
YUI Compressor和dojo shrinksafe在没有分号的情况下应该可以正常工作,因为它们基于完整的JavaScript解析器.但Packer和JSMin不会.
在语句结束时始终使用分号的另一个原因是,偶尔您可能会意外地将两个语句组合在一起以创建非常不同的语句.例如,如果您使用通用技术跟随语句来使用闭包创建范围:
var literal = { say: function(msg) { alert(msg); } } (function() { // .... })();
解析器可能会将括号解释为函数调用,这会导致类型错误,但在其他情况下,它可能会导致一个难以跟踪的细微错误.另一个有趣的事故是如果下一个语句以正则表达式开头,解析器可能会认为第一个正斜杠是一个除法符号.
JavaScript解释器执行称为"分号插入"的操作,因此如果没有分号的行有效,则会在语句末尾静静地添加分号,并且不会发生错误.
var foo = 'bar' // Valid, foo now contains 'bar' var bas = { prop: 'yay!' } // Valid, bas now contains object with property 'prop' containing 'yay!' var zeb = switch (zeb) { ... // Invalid, because the lines following 'var zeb =' aren't an assignable value
不太复杂,至少在某些事情显然不正确时会抛出错误.但是有些情况下不会抛出错误,但由于分号插入,语句不会按预期执行.考虑一个应该返回一个对象的函数:
return { prop: 'yay!' } // The object literal gets returned as expected and all is well return { prop: 'nay!' } // Oops! return by itself is a perfectly valid statement, so a semicolon // is inserted and undefined is unexpectedly returned, rather than the object // literal. Note that no error occurred.
像这样的bug可能令人抓狂,而且你无法确保这种情况永远不会发生(因为我不知道如何关闭分号插入),当你明确表达你的意图时,这些类型的错误更容易识别一直使用分号.明确添加分号通常被认为是好的风格.
在阅读Douglas Crockford精湛而简洁的书" JavaScript:The Good Parts " 时,我第一次意识到这种阴险的可能性.我强烈推荐它.