在JavaScript中进行对象文字赋值后是否需要分号?

时间:2008-09-03 18:16:17

标签: javascript

以下代码说明了分配的对象文字,但之后没有分号:

var literal = {
    say: function(msg) { alert(msg); }
}
literal.say("hello world!");

这似乎是合法的,并且不会发出警告(至少在Firefox 3中)。这是完全合法的,还是有严格版本的JavaScript不允许这样做?

我特别想知道未来的兼容性问题...我想写“正确的”JavaScript,所以如果从技术上讲我需要使用分号,我想使用它。

7 个答案:

答案 0 :(得分:36)

从技术上讲,JavaScript在许多情况下都有分号作为可选项。

但是,作为一般规则,在任何声明的最后使用它们。为什么?因为如果您想要压缩脚本,它将使您免于无数个小时的挫折。

自动分号插入由解释程序执行,因此如果您愿意, 可以将其留空。在评论中,有人声称

  

分号对于break / continue / throw

等语句不是可选的

但这是不正确的。它们是可选的;真正发生的是线路终结器影响自动分号插入;这是一个微妙的差异。

以下是分号插入标准的其余部分:

  

但是,为方便起见,在某些情况下可能会从源文本中省略这样的分号。这些情况通过说在这些情况下分号自动插入源代码令牌流来描述。

答案 1 :(得分:13)

YUI Compressor和dojo shrinksafe在没有分号的情况下应该可以正常工作,因为它们基于完整的JavaScript解析器。但Packer和JSMin不会。

在语句结尾处始终使用分号的另一个原因是,偶尔您可能会意外地将两个语句组合在一起以创建非常不同的语句。例如,如果您遵循使用常用技术的语句来使用闭包创建范围:

var literal = {
    say: function(msg) { alert(msg); }
}
(function() {
    // ....
})();

解析器可能会将括号解释为函数调用,这会导致类型错误,但在其他情况下,它可能会导致一个难以跟踪的细微错误。另一个有趣的事故是如果下一个语句以正则表达式开头,解析器可能会认为第一个正斜杠是一个除法符号。

答案 2 :(得分:8)

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.

像这样的错误可能令人抓狂,而且你不能确保这种情况永远不会发生(因为我无法知道关闭分号插入),这些类型的错误是通过始终使用分号来表达您的意图时更容易识别。那明确添加分号通常被认为是好的风格。

在阅读Douglas Crockford's精湛而简洁的书“JavaScript: The Good Parts”时,我第一次意识到这种潜在的隐蔽性。我高度推荐它。

答案 3 :(得分:3)

在这种情况下,语句末尾不需要分号。结论是一样的,但推理已经过时了。

JavaScript没有分号作为“可选”。相反,它有关于自动分号插入的严格规则。对于breakcontinuethrow等语句,分号不是可选的。有关详细信息,请参阅ECMA Language Specification;特别是11.9.1, rules of automatic semicolon insertion

答案 4 :(得分:0)

使用JSLint保持JavaScript干净整洁

JSLint说:

  

错误:

     

隐含的全球:警报2

     

第3行问题2:缺失   分号。

     

}

答案 5 :(得分:0)

没有必要使用分号。有些人选择遵循总是以分号结束的约定,而不是允许JavaScript在换行时自动执行,但我相信你会找到提倡任意一个方向的团体。

如果您正在考虑编写“正确”的JavaScript,我建议您在Firefox中使用设置为true的javascript.options.strict(通过about:config访问)进行测试。它可能无法捕获所有内容,但它可以帮助您确保JavaScript代码更加合规。

答案 6 :(得分:-1)

这是无效的(请参阅下面的说明)JavaScript代码,因为赋值只是一个常规语句,与

没有区别
var foo = "bar";

由于JavaScript解释器尝试添加分号来修复语法错误,因此可以省略分号,但这是一个额外且不必要的步骤。我不知道任何严格的模式,但我知道自动解析器或压缩器/混淆器需要分号。

如果您想编写正确的JavaScript代码,请编写分号: - )

根据ECMAscript规范http://www.ecma-international.org/publications/standards/Ecma-262.htm,如果缺少分号,则会自动插入分号。这使得脚本作者不需要它们,但这意味着它们是解释器所必需的。这意味着原始问题的答案是“否”,在编写脚本时不需要它们,但是,正如其他人所指出的那样,建议将其用于各种原因。