JavaScript 的“for-in”循环中是“var”还是没有“var”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5717126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:34:43  来源:igfitidea点击:

"var" or no "var" in JavaScript's "for-in" loop?

javascriptsyntaxfor-in-loop

提问by futlib

What's the correct way to write a for-inloop 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 xis explicitly declared:

for-in在 JavaScript 中编写循环的正确方法是什么?浏览器不会对我在这里展示的两种方法中的任何一种提出投诉。首先,有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) {
    ...
}

回答by Gabriel Llamas

Use var, it reduces the scope of the variable otherwise the variable looks up to the nearest closure searching for a varstatement. If it cannot find a varthen 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语句。如果它找不到 avar那么它是全局的(如果您处于严格模式using strict,则全局变量会抛出错误)。这可能会导致如下问题。

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

If you write var iin the for loop the alert shows 2.

如果您var i在 for 循环中写入警报,则会显示2

JavaScript Scoping and Hoisting

JavaScript 范围和提升

回答by Claudiu

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 xis 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 xis 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 xis one and the same it will alert hey, there, there, hey, there, there. You don't want that! Use var xin your forloops.

你可能会想到这警报heythereheliheytherecopter,但因为x是一个,它会提醒一样heytherethereheytherethere。你不想那样!var x在您的for循环中使用。

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

最重要的for是:如果循环在全局作用域中(即不在函数中),则局部作用域(x如果使用var x则在中声明作用域)与全局作用域相同(作用域x在中隐式声明)如果不使用xvar),则两个版本将相同。

回答by Pointy

You really should declare local variables with var, always.

你真的应该用var, always声明局部变量。

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 ... in”循环,除非您绝对确定这是您想要做的。为了迭代真实数组(这很常见),您应该始终使用带有数字索引的循环:

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 开始,该方法存在于 Array 原型中。

回答by user422039

Actually, if you dislike declaration within forheading, you can do:

实际上,如果您不喜欢for标题中的声明,您可以这样做:

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

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

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

回答by PSkocik

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 forblock. In fact, the vargets hoisted to the top of the enclosing scope (function) so a local iwill be effectively available both before the forloop (after the beginning of the current scope/function) and after it.

在 C++ 中,变量的范围不限于for块。事实上,将var被提升到封闭作用域(函数)的顶部,因此ifor循环之前(在当前作用域/函数的开始之后)和循环之后,局部变量都将有效可用。

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 letkeyword (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 varor letor const(in ES6)) rather than implicit globals.

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

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

for(i=0; ...)或者for(i in ...)如果您使用"use strict";(如您应该)并且i未声明,则会失败。

回答by Joel Coehoorn

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. 隐式声明的变量具有不同的范围,这可能不是您想要的。

回答by TJHeuvel

Using varis 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/for...in

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

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

回答by neebz

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 是否已经存在于其他地方。

回答by Matías Fidemraizer

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”变量在此上下文中可用,这将被循环的索引覆盖 - 那就是你会有一些逻辑错误 - 。