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

fut*_*lib 95 javascript syntax for-in-loop

for-in在JavaScript中编写循环的正确方法是什么?浏览器不会对我在此处显示的两种方法中的任何一种发出投诉.首先,有一种方法,其中x显式声明迭代变量:

for (var x in set) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

或者这种方法更自然地读取但对我来说似乎不正确:

for (x in set) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

Gab*_*mas 99

使用var,它减少了变量的范围,否则变量会查找最近的闭包搜索var语句.如果它找不到var则那么它是全局的(如果你处于严格模式using strict,全局变量会抛出错误).这可能导致如下问题.

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

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

JavaScript范围和提升

  • 不回答问题,这是正常的循环,而不是for for. (4认同)
  • 但是,来自Java,将`var`放在`for`头部看起来就像它在for循环中是本地的,它不是.因此,我更喜欢下面的user422039风格. (2认同)
  • 如果您在一个范围内碰巧有多个for循环怎么办?您将要么重用索引(无var),要么必须声明许多新变量(j,k,l,m,...),这些变量将永远不会再使用. (2认同)

Cla*_*diu 37

第一个版本:

for (var x in set) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

声明一个名为的局部变量x.第二个版本:

for (x in set) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

才不是.

如果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();
Run Code Online (Sandbox Code Playgroud)

你可能会想到这个提醒hey,there,heli,hey,there,copter,但因为x是一个,它会提醒一样hey,there,there,hey,there,there.你不希望这样!var x在你的for循环中使用.

最重要的for是:如果循环在全局范围内(即不在函数中),那么本地范围(x如果使用则声明范围var x)与全局范围相同(范围x在内容中隐式声明)如果你使用x没有var),那么两个版本将是相同的.

  • 最后一个完整的答案,解释和很好的例子.它真的回答了这个问题. (3认同)

Poi*_*nty 22

你真的应该使用var,始终声明局部变量.

你也不应该使用"for ... in"循环,除非你完全确定那是你想要做的.为了遍历真实数组(这是很常见的),你应该总是使用带有数字索引的循环:

for (var i = 0; i < array.length; ++i) {
  var element = array[i];
  // ...
}
Run Code Online (Sandbox Code Playgroud)

使用"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
  ...
});
Run Code Online (Sandbox Code Playgroud)

.forEach()方法存在于IE9的Array原型中.


use*_*039 12

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

var x;
for (x in set) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

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


Joe*_*orn 9

使用声明循环变量的那个var.隐式声明的变量具有不同的范围,可能与您的意图不同.


PSk*_*cik 8

for(var i = 0; ...)
Run Code Online (Sandbox Code Playgroud)

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

for(int i; ...)
Run Code Online (Sandbox Code Playgroud)

在C++中,变量没有作用于for块.事实上,var被提升到封闭范围(函数)的顶部,因此本地i将在for循环之前(在当前范围/函数开始之后)和之后有效地可用.

换句话说,做:

(function(){ //beginning of your current scope;
 //...
 for(var i in obj) { ... };
})();
Run Code Online (Sandbox Code Playgroud)

是相同的:

(function(){ //beginning of your current scope;
 var i;
 //...
 for(i in obj) { ... };
})();
Run Code Online (Sandbox Code Playgroud)

ES6具有let关键字(而不是var)将范围限制为for块.

当然,你应该使用局部变量(带有声明者varletconst而非隐含全局变量(在ES6)).

for(i=0; ...)或者for(i in ...)如果您使用"use strict";(如您所愿)并且i未被宣布将失败.


TJH*_*vel 6

使用var是最干净的方式,但两者都按照这里描述的方式工作:https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in

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


nee*_*ebz 5

由于性能原因,我认为var很好。

Javascript不会遍历整个全局范围来查看x是否在其他地方已经存在。