处理在多个 for 循环中声明的变量的最惯用方法是啥? [关闭]

Posted

技术标签:

【中文标题】处理在多个 for 循环中声明的变量的最惯用方法是啥? [关闭]【英文标题】:What is the most idiomatic way to handle variables declared in multiple for loops? [closed]处理在多个 for 循环中声明的变量的最惯用方法是什么? [关闭] 【发布时间】:2014-02-03 05:09:17 【问题描述】:

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 不喜欢最后一种方法。

有没有一种最惯用的或其他更可取的方法?

【问题讨论】:

我会使用最后两个之一。尽管有 JSHint 的抱怨,我还是喜欢最后一个;如果我不得不让它静音,我会使用前一个。 为了记录,JavaScript 正在获得块作用域。因此,接下来,您还将拥有 for (let i ...),它将声明 i 为循环的本地对象。 我更喜欢在两个循环之外声明i(但不一定在函数的顶部——请不要将它们全部放在一行/逗号分隔),但如果你发现自己做的太多,也许你需要更多的功能? Re: 版主——尽管这可能是基于意见的,但这仍然是一个人可能有的合理问题(尤其是那些学习编程的人)。我认为这个问题应该得到一个公平和平衡的答案。 【参考方案1】:

这实际上取决于您为谁编写代码。如果你正在为一家公司编码或为图书馆做贡献,你当然要遵循他们的风格指南。我已经看到图书馆中使用的所有这些(除了最后一个)。如果你喜欢 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);

无论如何,因为这是样式,我将参考几个库如何为每个循环编写它们:

jQuery uses the Crockford style in core 为 does lodash 下划线js使用last style as seen here。 Mootoolsalso uses this style

如果您的代码在发布之前要被最小化,那也没关系,因为缩小器会将其在处理过程中破坏为几乎相同的最终表示。

【讨论】:

他们建议在声明时初始化i,而不是在 for 循环的初始化部分? :(【参考方案2】:

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

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

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

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

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

【讨论】:

【参考方案3】:

另一个以不同方式回答问题的观点。

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

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

【讨论】:

【参考方案4】:

另一种方法是使用迭代器函数。例如,在现代浏览器中,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()

【讨论】:

【参考方案5】:

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

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

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

【讨论】:

以上是关于处理在多个 for 循环中声明的变量的最惯用方法是啥? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C 中的 for (;;) 循环中声明多个变量?

一次循环遍历 Javascript 数组多个元素的惯用方法是啥?

for循环变量声明为 final

同时改变多个结构字段的最快惯用方法是啥?

批处理中如何在for循环中使用 find命令 ,尤其是引用相对路径

Python:替换多个 for 循环、多个迭代器