为什么'for(列表中的var项)'与数组在JavaScript中被认为是不好的做法?

时间:2010-02-15 10:10:21

标签: javascript arrays loops

给出一个简单的基于零的数字索引数组:

var list = ['Foo', 'Bar', 'Baz'];

很多时候,我注意到有人建议循环遍历数组中的变量:

for(var item in list) { ... }

......几乎可以肯定有人认为这是不好的做法,并提出了另一种方法:

var count = list.length;

for(var i = 0; i < count; i++) {
    var item = list[i];
    ...
}

不使用上述更简单版本并使用第二个示例的原因是什么?

5 个答案:

答案 0 :(得分:83)

首先,对于for...in循环,循环的顺序是未定义的,因此无法保证按所需顺序迭代属性。

其次,for...in遍历对象的所有可枚举属性,包括从其原型继承的属性。对于数组,如果您的代码或页面中包含的任何库增加了Array的原型,这可能会影响您,这可能是一个真正有用的事情:

Array.prototype.remove = function(val) {
    // Irrelevant implementation details
};

var a = ["a", "b", "c"];

for (var i in a) {
    console.log(i);
}

// Logs 0, 1, 2, "remove" (though not necessarily in that order)

答案 1 :(得分:17)

速度?

for(..;..;..)循环证明比for .. in when I tested it here.

快36倍

Link courtesy this SO answer

答案 2 :(得分:1)

如果您使用for / in,item枚举字符串值“0”,“1”,...,那么不是列表中的实际对象。因此,第一个代码段中的“项目”更像是第二个代码段中的i,而不是item。此外,在您期望数字的位置枚举字符串值。当你对列表中的属性(例如array.ID = "a123")进行枚举时,你会遇到麻烦,因为它们也会被枚举。

但是有了这些缺点,如果你的团队知道它的作用,我仍然认为语法非常有用。

答案 3 :(得分:0)

添加list.foo = bar;并尝试使用简单的for。 如果你不使用某些库(比如prototypeJs)并且不向数组对象添加任何新属性 - 你可以使用简单的for-statement。

答案 4 :(得分:0)

for ... in ...不返回列表项,而是枚举数组属性。

仅出于这个原因,它不能代替for (i=0; i<arr.length; i++)循环。

适当的替代方法是for ... of ...构造。枚举可迭代对象(例如数组)的值。您可以在MDN Web文档上了解有关此内容的更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of

相关的现代浏览器支持它(Internet Explorer不计数,而是由Microsoft Edge代替)。如果您负担不起不支持较旧的浏览器的费用,那么这可能是可行的方法。您可以查看前面链接的MDN页面末尾的便捷浏览器支持表,以查看哪些浏览器版本实际上允许使用for ... of ...