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不喜欢最后一种方法。
是否有一种最惯用或更优选的方法?
答案 0 :(得分:3)
使用不同的变量我们没有问题。
重用和重新分配会降低代码的可读性,如果我们稍后删除声明,我们就会冒险将i分配给函数范围之外的东西。
在循环之外声明我,我们没有问题。
如果您的lint工具,IDE等抱怨,则重新提出将是一个问题。
所以我会争论第一或第三种选择。如果使用第一个选项关注变量的数量,那么您可能需要重构。
答案 1 :(得分:3)
这实际上取决于你编码的对象。如果您正在为公司编码或为图书馆做贡献,那么您当然应遵循他们的风格指南。我已经看到了图书馆中使用的所有这些(期望最后一次)。如果您喜欢Douglas Crockford风格,那么您将使用倒数第二个并将所有变量放在函数范围的顶部(或者jslint会对您大喊大叫)。
为例这被认为是好风格
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)
另一种以不同方式回答问题的内容。
具有多个循环的函数让我怀疑,因为:
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引擎解析的方式相同。