为什么在 JavaScript 中使用数组的“for(var item in list)”被认为是不好的做法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2265167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:31:34  来源:igfitidea点击:

Why is 'for(var item in list)' with arrays considered bad practice in JavaScript?

javascriptarraysloops

提问by Tatu Ulmanen

Given a simple zero based, numerically indexed array:

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

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

Many times, I have noticed that when someone suggests looping through variables in an array like this:

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

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

...there's almost certainly someone suggesting that that's bad practice and suggests an alternative approach:

...几乎可以肯定有人建议这是不好的做法并建议另一种方法:

var count = list.length;

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

What's the reasoning for not using the simpler version above and to use the second example instead?

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

回答by Tim Down

First, the order of the loop is undefined for a for...inloop, so there's no guarantee the properties will be iterated in the order you want.

首先,循环的顺序对于循环是未定义的for...in,因此不能保证属性会按照您想要的顺序进行迭代。

Second, for...initerates over all enumerable properties of an object, including those inherited from its prototype. In the case of arrays, this could affect you if your code or any library included in your page has augmented the prototype of Array, which can be a genuinely useful thing to do:

其次,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)

回答by Amarghosh

Speed?

速度?

for(..;..;..)loop proved to be 36 times faster than for .. inwhen I tested it here.

for(..;..;..)事实证明,循环比我在这里测试时快 36 倍for .. in

Link courtesy this SO answer

链接礼貌这个 SO 答案

回答by Alice

for ... in ...doesn't return items of list, but instead enumerates array properties.

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

For that reason alone, it cannotact as a replacement of for (i=0; i<arr.length; i++)loop.

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

The appropriate alternative is for ... of ...construct.It enumerates values of an iterable object, such as an array. You can read more about it on MDN Web Docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of

合适的替代方法是for ... of ...构建。它枚举可迭代对象的值,例如数组。您可以在 MDN Web Docs 上阅读更多相关信息:https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of

It's supported by the relevant modern browsers (Internet Explorer doesn't count, with it being replaced by Microsoft Edge). If you can afford not supporting older browsers, it's probably the way to go. You can check the convenient browser support table at the end of aforelinked MDN page to see which browser versions actually allow for ... of ...usage.

相关的现代浏览器都支持它(Internet Explorer 不算数,它被 Microsoft Edge 取代)。如果您负担不起不支持旧浏览器的费用,那么这可能是您要走的路。您可以查看前面链接的 MDN 页面末尾的便捷浏览器支持表,以查看实际允许for ... of ...使用哪些浏览器版本。

回答by Alice

If you use for/in like that, itemenumerates through string values "0", "1", ..., so not the actual objects in the list. So the the 'item' in the first snippet is more like the iin the second snippet,not the item. Furthermore string values are enumerated where you'd expect numbers. And you get in trouble when you properties to the list, like array.ID = "a123", as they will get enumerated also.

如果您像这样使用 for/in,则item枚举字符串值“0”、“1”、...,因此不是列表中的实际对象。所以第一个片段中的“项目”更像i是第二个片段中的,而不是item. 此外,在您期望数字的地方枚举字符串值。当您将属性添加到列表中时,您会遇到麻烦,例如array.ID = "a123",因为它们也会被枚举。

But with these downsides, I still think the syntax is very useful, if your team is aware of what it does.

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

回答by Adelf

Add list.foo = bar;and try to use simple for. If you don't use some libraries(like prototypeJs) and don't add any new properties to array object - you can use simple for-statement.

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