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

Posted

技术标签:

【中文标题】JavaScript“for-in”循环中的“var”还是没有“var”?【英文标题】:"var" or no "var" in JavaScript's "for-in" loop? 【发布时间】:2011-08-08 16:42:30 【问题描述】:

javascript 中编写for-in 循环的正确方法是什么?浏览器不会对我在这里展示的两种方法中的任何一种提出投诉。首先,有一种方法是显式声明迭代变量x

for (var x in set) 
    ...

另外,这种读起来更自然但对我来说似乎不正确的方法:

for (x in set) 
    ...

【问题讨论】:

在解决为什么 webpack 生成的捆绑文件在 for 循环中导致错误时遇到了这篇文章,其中 var 未用于声明迭代器 i:Uncaught ReferenceError: i is not defined。所以我将从现在开始使用它:/ webpack 奇怪地对待“全局”变量,更多信息请参见:***.com/a/40416826 【参考方案1】:

我总是使用 ES2015 中引入的 let 块作用域。

for (let x in set) 
    ...

Additional reading and examples

【讨论】:

【参考方案2】:

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

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

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

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

edit — 在 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
  ...
);

.forEach() 方法出现在 IE9 之前的 Array 原型中。

【讨论】:

在区分 Object for/in 循环与 Array for/length 循环方面,最好让您更清楚地使用 Array .forEach() 方法。【参考方案3】:
for(var i = 0; ...)

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

for(int i; ...)

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

换句话说,做:

(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 块的范围。

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

如果您使用"use strict";(应该如此)并且未声明ifor(i=0; ...)for(i in ...) 将失败。

【讨论】:

【参考方案4】:

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

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

【讨论】:

【参考方案5】:

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

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

正如该问题的其他答案所述,完全不使用 var 会产生不必要的副作用,例如分配全局属性。

【讨论】:

【参考方案6】:

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

如果你打算在 for 循环中使用循环的索引,而下一行中的其他人不需要这样做,最好用“var”声明变量,这样你就可以确定“x”是 for 循环的索引已初始化使用 0,而另一个,如果在此上下文中可以使用其他“x”变量,这将被循环的索引覆盖 - 那就是你会有一些逻辑错误 -。

【讨论】:

【参考方案7】:

使用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

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

JavaScript Scoping and Hoisting

【讨论】:

不回答问题,这是正常的for循环,不是for in。 i==5 的原因不是因为提升而不是 for 循环中缺少 var 吗? 另一个重要方面是严格模式禁止隐式创建全局属性,因此使用标准的“for in”循环而没有 var 语句实际上会失败并返回 ReferenceError。 但是,来自 Java,将 var 放入 for 头部看起来就像它在 for 循环中是本地的,但它不是。因此,我更喜欢下面user422039的风格。 如果你碰巧在一个范围内有多个 for 循环怎么办?您要么必须重用索引(无 var),要么必须声明大量新变量(j、k、l、m、...),这些变量将永远不会再使用。【参考方案8】:

第一个版本:

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();

您可能希望这会提醒heythereheliheytherecopter,但由于x 是一个并且相同,它会提醒heytherethereheytherethere。你不想要那个!在 for 循环中使用 var x

最重要的是:如果for 循环在全局范围内(即不在函数中),那么本地范围(如果您使用var x,则在其中声明范围x)是与全局作用域相同(如果使用不带 var 的 x,则隐式声明作用域 x),因此两个版本将相同。

【讨论】:

最后是一个完整的答案,带有解释和很好的例子。它确实回答了这个问题。【参考方案9】:

我认为 var 出于性能原因是好的。

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

【讨论】:

【参考方案10】:

使用用var 声明循环变量的那个。隐式声明的变量具有不同的范围,这可能不是您想要的。

【讨论】:

以上是关于JavaScript“for-in”循环中的“var”还是没有“var”?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript中的遍历

JavaScript 中的 for 循环---------------引用

javascript for-for vs for-in循环

JavaScript里的循环方法:forEach,for-in,for-of

JavaScript学习总结(变量for和for-in循环)

JavaScript里的循环方法之forEach,for-in,for-of