JavaScript变量定义:逗号 vs 分号

94
有没有使用逗号声明一组变量与使用分号声明有什么区别和/或优势?
例如:
var foo = 'bar', bar = 'foo';

对比

var foo = 'bar';
var bar = 'foo';

我知道如果在第一个示例的第一个变量上指定 var 关键字,它会持续存在于所有变量中,因此它们在作用域方面都会产生相同的最终结果。这只是个人偏好,还是以任何方式执行时都有性能优势?

10个回答

73

这并不会带来性能上的好处,只是个人选择和风格问题。

第一个版本更加简洁。


更新:

当然,从传输数据量的角度考虑,少一些是更好的,但你需要去掉大量 var 声明才能看到实际影响。

代码压缩 被提及为第一个示例可以帮助更好地进行代码压缩,但正如 Daniel Vassallo 在评论中指出的那样,一个好的代码压缩工具将自动为您完成,因此在这方面没有任何影响。


8
当压缩 JavaScript 代码时,可以提高性能。 - Ryan Kinal
1
@Ryan Kinal - 在问题的哪个地方你看到了缩小的提及? - Oded
2
@Oded -- 缩小文件大小与性能问题是一致的。因此,如果某种风格更适合缩小文件大小,那么它间接地适用于性能问题。 - STW
7
@Ryan:好的代码缩小器,比如Google Closure Compiler会将多个变量声明合并为一个:http://img840.imageshack.us/img840/3601/closurecompilerservice.jpg - Daniel Vassallo
2
是的,你说得对。出于好奇,我创建了一个测试(http://jsperf.com/var-declarations-multiple-vs-single-and-top-vs-all-over),运行了5次,得到了5个不同的答案。所以,嗯,这一切都关乎风格和个人偏好,而不是性能。 - Derek Henderson
显示剩余7条评论

30

在阅读了Crockford和其他资料后,我开始只使用逗号来链接我的变量。然后后来,我真的对Chrome DevTools调试器感到很恼火,它不会停在使用逗号定义变量的位置上。对于调试器来说,使用逗号链接的变量定义是一个语句,而多个var语句则是多个语句,调试器可以在这些语句处停止。因此,我又从逗号链接回到了:

var a = doSomethingA,
    b = doSomethignB,
    c = doSomethingC;

收件人:

var a = doSomethingA;
var b = doSomethignB;
var c = doSomethingC;

到目前为止,我认为第二个变体更加简洁,更不用说它解决了调试器问题的优势。

“通过网络发送少量代码”这一论点并不具有说服力,因为有压缩工具存在。


1
我自己也经历过这种情况。通常我会在需要检查某些东西的地方拆分声明,然后放一个debugger,再添加另一个var并继续使用逗号链接它们。然后当我完成调试后,我会回去删除debugger和额外的var - Collin Klopfenstein
8
第二种变量形式可以让 Git 历史记录更加清晰。在添加另一个变量之前,不需要将分号改为逗号或者冒险创建全局变量,只需要添加完整的 var 语句即可。 - payne8
提到第一种形式可能会误导你认为 b 或 c 是全局变量。 - garg10may

18

我更喜欢使用每个变量一个 var的写法:

var a = 2
var b = 3

因为其他使用逗号代替另一个变量的符号表示法有以下三个缺点:

1. 难以维护
考虑以下代码:

var a = 1,
    b = mogrify(2),
    c = 3

不过,嘿,mogrify是做什么用的呢?让我们打印变量b来找出答案:

var a = 1,
    b = mogrify(2),
    console.log(b)
    c = 3

破坏事物

2. 阅读困难

在行首的 var 清晰地表明将会初始化新变量。

var get_all_unicorn_promise = db.get_all_unicorns((unicorn) => {
        unicorn.legs.map((leg) => {
            leg.log('yes')
        })
    }).sort(),
    c = 3

这个 c = 3 是什么鬼?

3. 不一致

考虑以下内容:

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

使用 var-per-variable 每个声明都遵循相同的结构。 使用 comma-instead-of-another-var 第一个变量的声明方式与其他变量不同。 如果您决定将第一个变量移动到 for 循环内部,您将不得不在声明中间添加 var。

除了个人喜好外,似乎大多数知名项目都使用 var-per-variable 符号。


关于编程的内容翻译如下:要看到这种丑陋风格(逗号代替另一个变量)所带来的困惑,可以参考以下链接:https://stackoverflow.com/questions/37332155/confusing-use-of-commas-and-newlines-in-variable-assignment-expression-makes-var。 - Scott Weaver

7

我同意其他回答者的观点,这主要是个人风格问题。但为了引入一种“权威”的观点,以下是道格拉斯·克罗克福德流行的JSLint工具网站上的说法:

但由于JavaScript没有块级作用域,最好将函数所有变量声明放在函数顶部。建议每个函数只使用一个var语句。可以使用onevar选项来强制执行此操作。


6
值得注意的是,Mozilla Javascript(通过let语法)确实具有块级作用域。 - BlackVegetable
3
“let” 不仅仅可以在 Mozilla JS 中使用(参见此处)。它是 ES6 规范的一部分,但大多数浏览器仍在努力实现 ES6 的功能。 - mbomb007

3
正如其他人所指出的,这是一种风格偏好。如果你使用“好的部分”,JSLint 可能会告诉你每个函数只能有一个 var。因此,如果使用 JSLint 检查代码(在我看来不是坏主意),你将更多地使用前一种格式而不是后一种格式。
另一方面,同一位作者Douglas Crockford在他的编码规范中建议将每个变量放在自己的一行中。因此,如果您使用 JSLint,请取消“每个函数只有一个 var”复选框。;-)

1
他是正确的。在大多数编程语言中,将变量放在单独的行上是推荐的,因为源代码控制合并算法通常通过将每行作为纯文本(而不是行内的词汇语句)进行比较。如果两个人编辑同一个函数,在同一行声明多个变量几乎肯定会导致合并冲突,而单独的行几乎总是可以自动合并。(无论它们是作为单独的“var”语句声明还是用逗号链接。) - Richard Dingwall
他是正确的。更准确地说,Heretic是正确的。Crockford在某个时候改变了建议和JSLint代码。它曾经要求每个块只有一个var,可能有多个变量。现在它不仅支持letconst(但然后正确禁止var),而且对于每个变量都_需要_单独的声明。这是JSLint最明显的180度转变之一。 - ruffin

2

在我看来,个人偏好是唯一的区别,没有明显的差异。

我不喜欢有多个变量声明,所以通常会这样做:

var 
   one
  ,two
  ,three
  ,four
;

由于它更短且更易读,因此没有var噪音需要查看。


23
“arguably”关键词的意思是“有争议的”。如果我在我们的样本中发现了这个例子,它会很快变成var one, two, three four;。在JavaScript中为了多加行数而增加代码行可能是危险的(JS解释器可能会插入自己的;--如果你没有预料到这一点,那么你很快就会发现副作用。此外,前导,令我不舒服,关键字单独一行也让我不舒服,;单独一行也让我不舒服。你是按行计费吗? - STW
8
@STW - 你让自动分号插入听起来像是一个随机的事情,取决于不同浏览器的个人喜好,但实际上它只会按照一套明确定义的规则发生,你不必担心它可能会在你的var声明中间发生。(虽然我同意你关于前导逗号、var和最后的分号都要独占一行的看法 - 这三个问题也让我感到不舒服。) - nnnnnn
1
我认为这并没有真正回答问题,因为问题不是关于个人偏好的。 - Keith Pinson

2

由于我没有看到相关的参考资料,这里是ECMA-262规范的链接,该规范是JavaScript的基础规范。该页面中的语法如下:

12.2 Variable Statement

Syntax

  VariableStatement :
    var VariableDeclarationList ;

  VariableDeclarationList :
    VariableDeclaration
    VariableDeclarationList , VariableDeclaration

  VariableDeclarationListNoIn :
    VariableDeclarationNoIn
    VariableDeclarationListNoIn , VariableDeclarationNoIn

  VariableDeclaration :
    Identifier Initialiseropt

  VariableDeclarationNoIn :
    Identifier InitialiserNoInopt

  Initialiser :
    = AssignmentExpression
  InitialiserNoIn :
    = AssignmentExpressionNoIn

你可以从中看出,使用逗号或不使用逗号并不重要。无论哪种方式,它最终都被解析为VariableDeclaration并被完全相同地处理。脚本引擎处理这两个声明应该没有区别。唯一的区别是其他答案已经提到的 - 节省更多空间以及在编译脚本时应用语法查找所有VariableDeclarations所花费的时间几乎不可测量。

2

我更喜欢第二个版本(每个都有自己的var)。我认为这是因为我来自C++背景。在C++中,你可以像你在第一个例子中那样声明变量,但这是不被赞同的(当你试图以这种方式创建指针时,很容易出现错误)。


1
有趣的观点,但我不确定这是否回答了这种JavaScript语法的实际优缺点问题。 - Keith Pinson

1
如果你正在压缩你的JavaScript代码,那么有一个相当大的好处:
var one, two, three, four;

变成

var a, b, c, d;

var one;
var two;
var three;
var four;

变成

var a;
var b;
var c;
var d;

这是另外三个var实例,随着时间的推移可能会累加起来。

请参阅"A List Apart"文章系列"更好的Javascript压缩"第1部分第2部分


6
好的代码压缩器(例如Google Closure Compiler)可以将多个var语句合并为一个:http://img840.imageshack.us/img840/3601/closurecompilerservice.jpg。因此,这个论点只在您使用不太智能的压缩器时才成立...而您不应该使用它 :) - Daniel Vassallo
2
如果你正在使用gzip压缩,重复的“var”不会显著增加压缩后的文件大小(如果我正确理解了gzip)。 - Paul D. Waite

1

第一种方法可以节省一些字符--因此在JS文件大小和带宽消耗方面会有微小的节省。只有在极端情况下才会注意到这一点。


假设您没有对文件进行缩小处理——而且,现在谁不会对文件进行缩小处理呢? - Keith Pinson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接