处理多个for循环中声明的变量的最惯用方法是什么?

时间:2014-01-14 22:33:40

标签: javascript idioms

JavaScript只有函数范围。因此,for循环中声明的变量对于整个函数是可见的。

例如,

function foo() {
    for(var i = 0; i < n; i++) {
        // Do something
    }
    // i is still in scope here
}

当我们有多个for循环时,这就打开了我们如何处理这些其他for循环中的变量的问题。

我们使用不同的变量吗?

for(var i = 0; i < n; i++) { }
for(var j = 0; j < n; j++) { }

或者我们使用相同的变量但只是分配一个值(而不是声明它)?

for(var i = 0; i < n; i++) { }
for(i = 0; i < n; i++) { }

或者在循环之外声明i

var i;
for(i = 0; i < n; i++) { }
for(i = 0; i < n; i++) { }

或重新声明i

for(var i = 0; i < n; i++) { }
for(var i = 0; i < n; i++) { }

所有这些工作(或至少他们在我的浏览器的最新版本上)。 JSHint不喜欢最后一种方法。

是否有一种最惯用或更优选的方法?

5 个答案:

答案 0 :(得分:3)

使用不同的变量我们没有问题。

重用和重新分配会降低代码的可读性,如果我们稍后删除声明,我们就会冒险将i分配给函数范围之外的东西。

在循环之外声明我,我们没有问题。

如果您的lint工具,IDE等抱怨,则重新提出将是一个问题。

所以我会争论第一或第三种选择。如果使用第一个选项关注变量的数量,那么您可能需要重构。

答案 1 :(得分:3)

这实际上取决于你编码的对象。如果您正在为公司编码或为图书馆做贡献,那么您当然应遵循他们的风格指南。我已经看到了图书馆中使用的所有这些(期望最后一次)。如果您喜欢Douglas Crockford风格,那么您将使用倒数第二个并将所有变量放在函数范围的顶部(或者jslint会对您大喊大叫)。

jQuery style guide

为例

这被认为是好风格

var i = 0;

if ( condition ) {
    doSomething();
}

while ( !condition ) {
    iterating++;
}

for ( ; i < 100; i++ ) {
    object[ array[ i ] ] = someFn( i );
}

虽然风格不佳

// Bad
if(condition) doSomething();
while(!condition) iterating++;
for(var i=0;i<100;i++) object[array[i]] = someFn(i);

无论如何,因为这是风格,我将引用几个库如何为每个循环编写它们:

如果您的代码在发布之前将被最小化,那么无关紧要,因为缩小器会将其处理成与处理中相同的结束表示。

答案 2 :(得分:3)

另一种以不同方式回答问题的内容。

具有多个循环的函数让我怀疑,因为:

  1. 可能做得太多,无论如何都应该分解,
  2. 最好在功能上更好地编写它并完全消除索引(它在某些each - / map - y函数中可用)

答案 3 :(得分:3)

另一种方法是使用迭代器函数。例如,在现代浏览器中,Array将采用forEach方法:

var items = ["one", "two", "three"];
var things = ["hello", "goodbye"];

items.forEach(function (item, index) {
   // Do stuff
});

things.forEach(function (item, index) {
   // Do stuff
});

如果您使用的是较旧的浏览器(或自定义集合),您可以创建自己的迭代器,如下所示:

Array.prototype.forEach = function(callback) {       
   for(var i = 0; i < this.length; i++) {
      callback.apply(this, [this[i], i, this]);
   }
};

有关详细信息,请参阅:Array.prototype.forEach()

答案 4 :(得分:1)

函数内声明的任何变量都被解释为在函数开头声明。 Doug Crockford认为你应该在每个函数的第一行声明所有变量。

doSomething = function() {
   var i, ... other variables ...;
   ...
   for (i = 0; i < x; i += 1) {
      ...
   }
   ...
   for (i = 0; i < x; i += 1) {
      ...
   }
}

这样代码的读取方式与javascript引擎解析的方式相同。