在JavaScript的“forin”循环中是“var”还是“var”?

时间:2022-11-30 22:33:51

What's the correct way to write a for-in loop in JavaScript? The browser doesn't issue a complaint about either of the two approaches I show here. First, there is this approach where the iteration variable x is explicitly declared:

用JavaScript编写forin循环的正确方法是什么?浏览器不会对我在这里展示的两种方法中的任何一种发出抱怨。首先,有一种方法,它显式地声明迭代变量x:

for (var x in set) {
    ...
}

And alternatively this approach which reads more naturally but doesn't seem correct to me:

另外,这种方法读起来更自然,但在我看来并不正确:

for (x in set) {
    ...
}

9 个解决方案

#1


93  

Use var, it reduces the scope of the variable otherwise the variable looks up to the nearest closure searching for a var statement. If it cannot find a var then it is global (if you are in a strict mode, using strict, global variables throw an error). This can lead to problems like the following.

使用var,它会减少变量的范围,否则变量会查找最近的闭包来搜索var语句。如果找不到var,那么它就是全局变量(如果您处于严格模式,使用严格的全局变量抛出一个错误)。这会导致以下问题。

function f (){
    for (i=0; i<5; i++);
}
var i = 2;
f ();
alert (i); //i == 5. i should be 2

If you write var i in the for loop the alert shows 2.

如果您在for循环中写入var i,则警告显示为2。

JavaScript Scoping and Hoisting

JavaScript范围和提升

#2


31  

The first version:

第一个版本:

for (var x in set) {
    ...
}

declares a local variable called x. The second version:

声明一个称为x的本地变量。

for (x in set) {
    ...
}

does not.

没有。

If x is already a local variable (i.e. you have a var x; or var x = ...; somewhere earlier in your current scope (i.e. the current function)) then they will be equivalent. If x is not already a local variable, then using the second will implicitly declare a global variable x. Consider this code:

如果x已经是一个局部变量(也就是说,你有一个var x;或var x =…;在当前作用域(即当前函数)前面的某个地方,它们将是等价的。如果x不是一个局部变量,那么使用第二个变量将隐式地声明一个全局变量x。

var obj1 = {hey: 10, there: 15};
var obj2 = {heli: 99, copter: 10};
function loop1() {
    for (x in obj1) alert(x);
}
function loop2() {
    for (x in obj2) {
        loop1(); 
        alert(x);
    }
}
loop2();

you might expect this to alert hey, there, heli, hey, there, copter, but since the x is one and the same it will alert hey, there, there, hey, there, there. You don't want that! Use var x in your for loops.

你可能会想到这里会发出警报,嘿,嘿,这里,直升机,但是因为x是一个,它会发出警报,嘿,那里,嘿,那里,那里。你不希望这样!在for循环中使用var x。

To top it all off: if the for loop is in the global scope (i.e. not in a function), then the local scope (the scope x is declared in if you use var x) is the same as the global scope (the scope x is implicitly declared in if you use x without a var), so the two versions will be identical.

最糟糕的是:如果for循环在全球范围(即不是一个函数),然后局部作用域(x范围中声明如果你使用var x)是一样的全局作用域范围(x是隐式中声明如果你使用x没有var),所以两个版本将是相同的。

#3


18  

You really should declare local variables with var, always.

总是应该用var来声明局部变量。

You also should not use "for ... in" loops unless you're absolutely sure that that's what you want to do. For iterating through real arrays (which is pretty common), you should always use a loop with a numeric index:

你也不应该使用“for…”在循环中,除非你完全确定这就是你想做的。对于遍历真实数组(这是很常见的),您应该始终使用带有数字索引的循环:

for (var i = 0; i < array.length; ++i) {
  var element = array[i];
  // ...
}

Iterating through a plain array with "for ... in" can have unexpected consequences, because your loop may pick up attributes of the array besides the numerically indexed ones.

遍历一个普通数组,并使用“for…”in“可能会产生意想不到的结果,因为循环可能会获取数组的属性,而不是数字索引的属性。

edit — here in 2015 it's also fine to use .forEach() to iterate through an array:

编辑——在2015年,使用.forEach()迭代数组也是可以的:

array.forEach(function(arrayElement, index, array) {
  // first parameter is an element of the array
  // second parameter is the index of the element in the array
  // third parameter is the array itself
  ...
});

The .forEach() method is present on the Array prototype from IE9 forward.

foreach()方法出现在IE9的数组原型中。

#4


11  

Actually, if you dislike declaration within for heading, you can do:

事实上,如果你不喜欢标题内的声明,你可以:

var x;
for (x in set) {
    ...
}

As mentioned in other answers to this question, not using var at all produces unnecessary side-effects like assigning a global property.

正如在这个问题的其他答案中提到的,不使用var会产生不必要的副作用,比如分配全局属性。

#5


9  

Use the one where you declare the loop variable with var. Implicitly declared variables have a different scope that's probably not what you intended.

使用带有var的循环变量。隐式声明的变量具有不同的作用域,这可能不是您想要的。

#6


6  

for(var i = 0; ...)

is a commonly seen pattern but it's different from

是一种常见的模式,但它是不同的

for(int i; ...)

in C++ in that that the variable isn't scoped to the for block. In fact, the var gets hoisted to the top of the enclosing scope (function) so a local i will be effectively available both before the for loop (after the beginning of the current scope/function) and after it.

在c++中,变量的作用域不是for块。实际上,var被提升到封闭作用域(函数)的顶部,因此本地i将在for循环之前(当前作用域/函数开始之后)和之后有效地可用。

In other words, doing:

换句话说,做:

(function(){ //beginning of your current scope;
 //...
 for(var i in obj) { ... };
})();

is the same as:

是一样的:

(function(){ //beginning of your current scope;
 var i;
 //...
 for(i in obj) { ... };
})();

ES6 has the let keyword (instead of var) to limit the scope to the for block.

ES6使用let关键字(而不是var)将范围限制为for块。

Of course, you SHOULD be using local variables (ones declared with either var or let or const (in ES6)) rather than implicit globals.

当然,您应该使用局部变量(使用var或let或const声明的变量(在ES6中)),而不是使用隐式全局变量。

for(i=0; ...) or for(i in ...) will fail if you use "use strict"; (as you should) and i isn't declared.

(我= 0;如果你使用“使用严格”,或(我在…)将失败;(你应该这么说)我没有被宣布。

#7


5  

Using var is the cleanest way, but both work as described here: https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in

使用var是最干净的方法,但是这里描述的是:https://developer.mozilla.org/en/javascript/reference/statements/forin

Basically, by using var you ensure that you create a new variable. Otherwise you might accidentally use a previously defined variable.

基本上,通过使用var,您可以确保创建一个新的变量。否则,您可能会意外地使用先前定义的变量。

#8


4  

I think var is good for performance reasons.

我认为var很适合性能。

Javascript won't look through the whole global scope to see if x already exists somewhere else.

Javascript不会检查整个全局范围,看看x是否已经存在于其他地方。

#9


3  

From a general point of view, first version will be for an index that must live within loop's scope, while the other one would be any variable in the scope where loop's constructor got invoked.

从一般的观点来看,第一个版本将用于必须位于循环范围内的索引,而另一个版本将是调用循环构造函数的范围中的任何变量。

If you're going to use loop's index inside for loop and this won't be required by others in next lines, better declare the variable with "var" so you'll be sure "x" is for loop's index initialized with 0, while the other one, if other "x" variable is available in this context, this will get overwritten by loop's index - that's you'll have some logical errors -.

如果你要使用循环的指数在for循环,这不会被别人需要在下一行,更好地与“var”声明的变量,这样你一定会“x”与0 for循环指数初始化,而另一个,如果其他“x”变量可以在这种情况下,这将被循环覆盖指数——你会有一些逻辑错误。

#1


93  

Use var, it reduces the scope of the variable otherwise the variable looks up to the nearest closure searching for a var statement. If it cannot find a var then it is global (if you are in a strict mode, using strict, global variables throw an error). This can lead to problems like the following.

使用var,它会减少变量的范围,否则变量会查找最近的闭包来搜索var语句。如果找不到var,那么它就是全局变量(如果您处于严格模式,使用严格的全局变量抛出一个错误)。这会导致以下问题。

function f (){
    for (i=0; i<5; i++);
}
var i = 2;
f ();
alert (i); //i == 5. i should be 2

If you write var i in the for loop the alert shows 2.

如果您在for循环中写入var i,则警告显示为2。

JavaScript Scoping and Hoisting

JavaScript范围和提升

#2


31  

The first version:

第一个版本:

for (var x in set) {
    ...
}

declares a local variable called x. The second version:

声明一个称为x的本地变量。

for (x in set) {
    ...
}

does not.

没有。

If x is already a local variable (i.e. you have a var x; or var x = ...; somewhere earlier in your current scope (i.e. the current function)) then they will be equivalent. If x is not already a local variable, then using the second will implicitly declare a global variable x. Consider this code:

如果x已经是一个局部变量(也就是说,你有一个var x;或var x =…;在当前作用域(即当前函数)前面的某个地方,它们将是等价的。如果x不是一个局部变量,那么使用第二个变量将隐式地声明一个全局变量x。

var obj1 = {hey: 10, there: 15};
var obj2 = {heli: 99, copter: 10};
function loop1() {
    for (x in obj1) alert(x);
}
function loop2() {
    for (x in obj2) {
        loop1(); 
        alert(x);
    }
}
loop2();

you might expect this to alert hey, there, heli, hey, there, copter, but since the x is one and the same it will alert hey, there, there, hey, there, there. You don't want that! Use var x in your for loops.

你可能会想到这里会发出警报,嘿,嘿,这里,直升机,但是因为x是一个,它会发出警报,嘿,那里,嘿,那里,那里。你不希望这样!在for循环中使用var x。

To top it all off: if the for loop is in the global scope (i.e. not in a function), then the local scope (the scope x is declared in if you use var x) is the same as the global scope (the scope x is implicitly declared in if you use x without a var), so the two versions will be identical.

最糟糕的是:如果for循环在全球范围(即不是一个函数),然后局部作用域(x范围中声明如果你使用var x)是一样的全局作用域范围(x是隐式中声明如果你使用x没有var),所以两个版本将是相同的。

#3


18  

You really should declare local variables with var, always.

总是应该用var来声明局部变量。

You also should not use "for ... in" loops unless you're absolutely sure that that's what you want to do. For iterating through real arrays (which is pretty common), you should always use a loop with a numeric index:

你也不应该使用“for…”在循环中,除非你完全确定这就是你想做的。对于遍历真实数组(这是很常见的),您应该始终使用带有数字索引的循环:

for (var i = 0; i < array.length; ++i) {
  var element = array[i];
  // ...
}

Iterating through a plain array with "for ... in" can have unexpected consequences, because your loop may pick up attributes of the array besides the numerically indexed ones.

遍历一个普通数组,并使用“for…”in“可能会产生意想不到的结果,因为循环可能会获取数组的属性,而不是数字索引的属性。

edit — here in 2015 it's also fine to use .forEach() to iterate through an array:

编辑——在2015年,使用.forEach()迭代数组也是可以的:

array.forEach(function(arrayElement, index, array) {
  // first parameter is an element of the array
  // second parameter is the index of the element in the array
  // third parameter is the array itself
  ...
});

The .forEach() method is present on the Array prototype from IE9 forward.

foreach()方法出现在IE9的数组原型中。

#4


11  

Actually, if you dislike declaration within for heading, you can do:

事实上,如果你不喜欢标题内的声明,你可以:

var x;
for (x in set) {
    ...
}

As mentioned in other answers to this question, not using var at all produces unnecessary side-effects like assigning a global property.

正如在这个问题的其他答案中提到的,不使用var会产生不必要的副作用,比如分配全局属性。

#5


9  

Use the one where you declare the loop variable with var. Implicitly declared variables have a different scope that's probably not what you intended.

使用带有var的循环变量。隐式声明的变量具有不同的作用域,这可能不是您想要的。

#6


6  

for(var i = 0; ...)

is a commonly seen pattern but it's different from

是一种常见的模式,但它是不同的

for(int i; ...)

in C++ in that that the variable isn't scoped to the for block. In fact, the var gets hoisted to the top of the enclosing scope (function) so a local i will be effectively available both before the for loop (after the beginning of the current scope/function) and after it.

在c++中,变量的作用域不是for块。实际上,var被提升到封闭作用域(函数)的顶部,因此本地i将在for循环之前(当前作用域/函数开始之后)和之后有效地可用。

In other words, doing:

换句话说,做:

(function(){ //beginning of your current scope;
 //...
 for(var i in obj) { ... };
})();

is the same as:

是一样的:

(function(){ //beginning of your current scope;
 var i;
 //...
 for(i in obj) { ... };
})();

ES6 has the let keyword (instead of var) to limit the scope to the for block.

ES6使用let关键字(而不是var)将范围限制为for块。

Of course, you SHOULD be using local variables (ones declared with either var or let or const (in ES6)) rather than implicit globals.

当然,您应该使用局部变量(使用var或let或const声明的变量(在ES6中)),而不是使用隐式全局变量。

for(i=0; ...) or for(i in ...) will fail if you use "use strict"; (as you should) and i isn't declared.

(我= 0;如果你使用“使用严格”,或(我在…)将失败;(你应该这么说)我没有被宣布。

#7


5  

Using var is the cleanest way, but both work as described here: https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in

使用var是最干净的方法,但是这里描述的是:https://developer.mozilla.org/en/javascript/reference/statements/forin

Basically, by using var you ensure that you create a new variable. Otherwise you might accidentally use a previously defined variable.

基本上,通过使用var,您可以确保创建一个新的变量。否则,您可能会意外地使用先前定义的变量。

#8


4  

I think var is good for performance reasons.

我认为var很适合性能。

Javascript won't look through the whole global scope to see if x already exists somewhere else.

Javascript不会检查整个全局范围,看看x是否已经存在于其他地方。

#9


3  

From a general point of view, first version will be for an index that must live within loop's scope, while the other one would be any variable in the scope where loop's constructor got invoked.

从一般的观点来看,第一个版本将用于必须位于循环范围内的索引,而另一个版本将是调用循环构造函数的范围中的任何变量。

If you're going to use loop's index inside for loop and this won't be required by others in next lines, better declare the variable with "var" so you'll be sure "x" is for loop's index initialized with 0, while the other one, if other "x" variable is available in this context, this will get overwritten by loop's index - that's you'll have some logical errors -.

如果你要使用循环的指数在for循环,这不会被别人需要在下一行,更好地与“var”声明的变量,这样你一定会“x”与0 for循环指数初始化,而另一个,如果其他“x”变量可以在这种情况下,这将被循环覆盖指数——你会有一些逻辑错误。