在顶部定义每个变量总是最好的方法吗?

时间:2011-02-19 19:40:42

标签: javascript variables

我听说在函数顶部定义变量是一种很好的技巧,所以最终不会出现变量提升问题。这样:

// Beginning of file

function something(){
    var a, b, c = 1, d, e;
    // Do something
}

// End of file

是一个很好的例子(当然不包括错误的变量名称)。

我的问题是:这总是最好的方法吗?如果你正在使用很多变量怎么办?他们真的应该只是在一条线上吗?

6 个答案:

答案 0 :(得分:47)

我强烈建议您阅读Code Complete 2 by Steve McConnell。他的论点是你既不应该在一行中声明所有变量 ,也不应该在例程的顶部声明它们。所以,不要这样做:

function foo() {
    var a,
        b,
        c,
        d;

     /**
      * 20 lines that use a and b
      */

     /**
      * 10 lines that use c and d
      */
}

相反,您应该将变量声明为接近需要的位置。在上面的代码中,可能如下所示:

function foo() {
    var a,
        b;

     /**
      * 20 lines that use a and b
      */

     var c,
         d;

     /**
      * 10 lines that use c and d
      */
}

这样做的好处是,只需查看上面的声明,您就可以快速了解一段代码所使用的变量。您不需要阅读代码来查看设置了哪些变量,只是声明了哪些变量。

不要为编译器或计算机编写代码。写给开发人员。您的代码应尽可能易于阅读,并且需要尽可能少的努力来理解特定的代码部分。

答案 1 :(得分:29)

“他们真的应该只被排在一条线上吗?”

我不这么认为。

以下是我将如何编写(忽略名称):

function something(){
    var a,
        b,
        c = 1,
        d,
        e;
    // Do something
}

这只在上面的中看起来很愚蠢,因为1)名称很糟糕2)变量未在“声明”中分配 - 大多数代码可以使用不可变(一次分配)变量编写我发现这可以简化代码。我使用它有多种原因,包括清晰度和对格式化更改的抵制(也就是说,我可以更改初始值,添加/删除声明等,而不会弄乱其他行的格式)。

“在顶部定义每个变量总是最好的方法吗?”

我不这么认为。

例如,以下是我编写循环的方法:

for (var i = 0; i < x; i++) {
  var elm = elms[i];
  ...
}

有些人会说“但是这些功能已经被提升到了最重要的位置!”或者“变量是功能性的!”。嗯,的确如此。但是,这使我能够轻松直观看到这是一个错误,即使JavaScript引擎无法帮助:

for (var i = 0; i < x; i++) {
  var elm = elms[i];
  ...
}
...
// valid JS but since I consider this construct *invalid*
// I know this is a *bug* in my code
alert(elm);

当我分配到闭包中捕获的变量时:它取决于。如果变量仅在一个闭包中使用,我通常将它放在正上方。这让我知道只应该用在那个闭包中。如果变量是共享的(例如self),我将它放在所有适用的闭包之上 - 通常在函数的“变量声明部分”中。这让我知道它有一个“功能范围”(读取:可能用于多个绑定)。

要解决“for-each-closure”问题 - 只需学习语言即可。保持变量“声明”接近闭包不会影响到这一点。如果不理解构造,那么如何编写代码并不重要。

我将这些方法用于/因为:

  1. 具有一致的易于扫描的代码。
  2. 编写告诉我何时出错的代码
  3. 我更喜欢可修改的代码而不改变结构。
  4. 自我记录代码意味着更少的评论。
  5. 我喜欢“垂直阅读”
  6. 快乐的编码。

答案 2 :(得分:13)

在具有块范围的语言中,通常建议在首次使用的站点声明变量。

但是因为JavaScript没有块范围,所以在函数顶部声明所有函数的变量是明智的。这样你就不会欺骗自己或其他人关于变量的范围。

编辑:许多人同时使用多种语言。通常,JavaScript是其中唯一没有块范围的。

答案 3 :(得分:7)

这是一个风格问题。不是功能问题。

javascript解析器将采用此代码

function() {
   dostuff();
   var i = 4;
}

并将其转换为:

function() {
   var i;
   dostuff();
   i = 4;
}

至于风格问题。不,谢谢,我以为我们用ANSI C留下了它。

您要做的是在“范围”

的顶部声明函数

如果变量的“范围”是整个函数,则在顶部声明它们。如果“范围”是函数的子集,则在子集的开头声明它们。

将“范围”视为逻辑范围而不是功能范围。

这应该确保最大的可读性。

答案 4 :(得分:4)

我敢说,在较旧的结构中(例如C \ C ++天),初始化变量并为它们分配起始值非常重要。但随着事情的发展,我发现在“必要时”声明它们是一个有效的实现。除非范围正在发挥作用(例如,你不仅需要在该函数中使用变量a,而且在其他函数中也需要变量{{1}},我会在移动中声明。

也许这只是思考方式,但我倾向于根据范围声明事物(如果仅在if条件或几行代码中需要变量,我会在那里声明它(而不是在顶部)我的函数/类)。如果我没有通过那个代码路径,我认为它保存了内存分配,并且它不会被“无理由”声明。)

然而,我可能完全错了。无论哪种方式,JavaScript都允许您以您认为最容易阅读的任何方式声明变量。

答案 5 :(得分:4)

这实际上只是一个偏好问题。例如,如果我的方法只包含for循环,那么我不会将循环变量提取到顶部:

var func = function(arr) {
    for (var i = 0, len = arr.length; i < len; i++) {
        // array processing here
    }
}

几乎所有其他时间虽然我会将所有变量放在顶部以提升原因。如果您发现函数顶部有太多变量,则可能表明您的方法做了太多工作,并且应该考虑将其中的一部分提取到某种辅助方法中。这样您就可以根据功能组织变量。