2014-01-14 18 views
12

JavaScript只有函数范围。因此,在for循环中声明的变量对于整个函数是可见的。处理在多个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++) { } 

或redeclare i

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

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

有没有一种最习惯的方法?

+1

我会使用最后两个之一。尽管JSHint的投诉,我喜欢最后一个;如果我必须保持沉默,我会使用前一个。 – Barmar

+4

为了记录,JavaScript正在获得块范围。所以,今后,你还会['for(let i ...)'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let),它会将'i'声明为循环的本地。 –

+1

我更喜欢在两个循环之外声明'i'(但不一定在函数的顶部 - 请不要将它们全部放在一行/逗号分隔的位置),但是如果您发现自己正在执行此操作太多了,也许你需要更多的功能? – Ryan

回答

3

这实际上取决于你是谁编码。如果你正在为公司编码或为图书馆做出贡献,你当然会遵循他们的风格指南。我已经看到了所有这些(期待最后)在库中使用。如果你喜欢道格拉斯克罗克福德式的风格,你可以倒数第二,把所有的变量放在函数范围的顶部(否则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); 

无论如何,因为这是风格我将参考几个库为每个库编写它们的方式哎呀:

如果你的代码将被最小化,你放开它之前,都不会有问题的minifiers将裂伤它几乎同一端的处理表示。

+0

他们建议在声明时初始化'i',而不是在for循环的初始化部分? :( –

3

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

重复使用和重新分配会使代码更不可读,如果我们稍后再删除声明,我们就会冒险将i分配给函数作用域之外的某个东西。

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

如果你的lint工具,IDE等抱怨,重新声明将是一个问题。

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

1

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

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

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

3

另一个需要以不同的方式回答问题。

多有圈的功能让我怀疑这是因为:

  1. 它可能会做太多,无论如何都应该被分解,
  2. 这可能是更好的它更功能编写和消除指数共(它在某些each的可用 -/map -y功能反正)
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()

相关问题