for-in
在 JavaScript中编写循环的正确方法是什么?浏览器不会对我在这里展示的两种方法中的任何一种提出投诉。首先,有一种方法x
是显式声明迭代变量:
for (var x in set) {
...
}
或者,这种读起来更自然但对我来说似乎不正确的方法:
for (x in set) {
...
}
for-in
在 JavaScript中编写循环的正确方法是什么?浏览器不会对我在这里展示的两种方法中的任何一种提出投诉。首先,有一种方法x
是显式声明迭代变量:
for (var x in set) {
...
}
或者,这种读起来更自然但对我来说似乎不正确的方法:
for (x in set) {
...
}
使用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
如果您var i
在 for 循环中写入警报,则会显示2
.
第一个版本:
for (var x in set) {
...
}
声明一个名为 的局部变量x
。第二个版本:
for (x in set) {
...
}
才不是。
如果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();
您可能希望这会提醒hey
, there
, heli
, hey
, there
, copter
,但由于x
是一个且相同的,它会提醒hey
, there
, there
, hey
, there
, there
. 你不想要那个!var x
在你的for
循环中使用。
最重要的是:如果for
循环在全局范围内(即不在函数中),则本地范围(x
如果使用 ,则声明范围var x
)与全局范围相同(范围x
隐式声明在如果你x
不使用 var),那么这两个版本将是相同的。
var
你真的应该用, always声明局部变量。
你也不应该使用“for ... in”循环,除非你完全确定那是你想要做的。对于遍历真实数组(这很常见),您应该始终使用带有数字索引的循环:
for (var i = 0; i < array.length; ++i) {
var element = array[i];
// ...
}
使用“for ... in”遍历普通数组可能会产生意想不到的后果,因为您的循环可能会获取数组的属性,而不是数字索引的属性。
编辑——在 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
...
});
从 IE9 开始,该.forEach()
方法出现在 Array 原型上。
实际上,如果你不喜欢for
标题中的声明,你可以这样做:
var x;
for (x in set) {
...
}
正如该问题的其他答案所述,根本不使用var
会产生不必要的副作用,例如分配全局属性。
使用用 . 声明循环变量的那个var
。隐式声明的变量具有不同的范围,这可能不是您想要的。
for(var i = 0; ...)
是一种常见的模式,但它不同于
for(int i; ...)
在 C++ 中,变量的范围不限于for
块。事实上,var
被提升到封闭范围(函数)的顶部,因此本地i
将在for
循环之前(当前范围/函数开始之后)和循环之后有效。
换句话说,做:
(function(){ //beginning of your current scope;
//...
for(var i in obj) { ... };
})();
是相同的:
(function(){ //beginning of your current scope;
var i;
//...
for(i in obj) { ... };
})();
ES6 有let
关键字(而不是var
)来限制 for 块的范围。
当然,你应该使用局部变量(在 ES6 中使用var
orlet
或 or声明的变量const
)而不是隐式全局变量。
for(i=0; ...)
或者for(i in ...)
如果你使用"use strict";
(你应该)并且i
没有被声明,将会失败。
使用var
是最干净的方式,但两者都按此处所述工作:https ://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in
基本上,通过使用var
您确保您创建了一个新变量。否则,您可能会意外使用先前定义的变量。
我认为 var 出于性能原因是好的。
Javascript 不会查看整个全局范围以查看 x 是否已经存在于其他地方。
从一般的角度来看,第一个版本将用于必须存在于循环范围内的索引,而另一个版本将是调用循环构造函数的范围内的任何变量。
如果你打算在 for 循环中使用循环的索引,而下一行中的其他人不需要这样做,最好用“var”声明变量,这样你就可以确定“x”是用 0 初始化的 for 循环的索引,而另一个,如果其他“x”变量在这种情况下可用,这将被循环的索引覆盖 - 那就是你会有一些逻辑错误 -。