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

Javascript 处理在多个for循环中声明的变量的最惯用方法是什么?,javascript,idioms,Javascript,Idioms,JavaScript只有函数作用域。因此,for循环中声明的变量对于整个函数都是可见的 doSomething = function() { var i, ... other variables ...; ... for (i = 0; i < x; i += 1) { ... } ... for (i = 0; i < x; i += 1) { ... } } 比如说, function foo() { f

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

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

function foo() {
    for(var i = 0; i < n; i++) {
        // Do something
    }
    // i is still in scope here
}
还是重新声明
i

for(var i = 0; i < n; i++) { }
for(var i = 0; i < n; i++) { }
for(var i=0;i
所有这些都可以工作(或者至少在我的浏览器的最新版本上可以)。但他不喜欢最后一种方法


有一种方法是最惯用的还是更可取的?

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

重用和重新分配会降低代码的可读性,如果我们稍后删除声明,则可能会将i分配给函数范围之外的内容

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

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


所以我会支持第一个或第三个选择。如果使用第一个选项需要考虑变量的数量,那么您可能需要重构。

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

doSomething = function() {
   var i, ... other variables ...;
   ...
   for (i = 0; i < x; i += 1) {
      ...
   }
   ...
   for (i = 0; i < x; i += 1) {
      ...
   }
}
doSomething=函数(){
var i,…其他变量。。。;
...
对于(i=0;i

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

这实际上取决于您为谁编写代码。如果你正在为一家公司编码或为一个库做贡献,你当然要遵循他们的风格指南。我见过所有这些(除了最后一个)在图书馆中使用。如果您喜欢Douglas Crockford样式,那么您将选择倒数第二个,并将所有变量放在函数范围的顶部(否则jslint会对您大喊大叫)

以以下表格为例:

这被认为是好的风格

var i = 0;

if ( condition ) {
    doSomething();
}

while ( !condition ) {
    iterating++;
}

for ( ; i < 100; i++ ) {
    object[ array[ i ] ] = someFn( i );
}
var i=0;
如果(条件){
doSomething();
}
而(!条件){
迭代++;
}
对于(;i<100;i++){
对象[array[i]]=someFn(i);
}
虽然这是一种差劲的风格:

// Bad
if(condition) doSomething();
while(!condition) iterating++;
for(var i=0;i<100;i++) object[array[i]] = someFn(i);
//坏的
if(条件)doSomething();
当(!条件)迭代时++;
对于(var i=0;i另一个以不同方式回答问题的例子

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

  • 它可能做得太多,无论如何都应该分解,并且
  • 更好的做法可能是编写更具功能性的代码,并完全消除索引(它在一些
    每个
    -/
    映射
    -y函数中都可用)

  • 另一种方法是使用迭代器函数。例如,在现代浏览器中,
    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=函数(回调){
    for(var i=0;i

    有关更多信息,请参见:

    我会使用最后两个选项中的一个。尽管JSHint抱怨,我还是喜欢最后一个选项;如果必须使其静音,我会使用前一个选项。作为记录,JavaScript正在获得块范围。因此,继续,您也会有,它将
    I
    声明为循环的本地选项。我更喜欢声明
    I
    一次在两个循环之外(但不一定在函数的顶部-请不要将它们全部放在一行/逗号分隔的位置),但如果您发现自己做得太多,可能需要更多的函数?回复:版主-尽管这可能是基于意见的,但这仍然是一个合理的问题(特别是那些学习编程的人)。我认为这个问题应该得到一个公平而平衡的答案。他们建议在声明时初始化
    I
    ,而不是在for循环的初始化部分:(
    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]);
       }
    };