给出一个简单的基于零的数字索引数组:
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];
...
}
不使用上述更简单版本并使用第二个示例的原因是什么?
答案 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)
答案 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 ...
。