【问题标题】:Why does for...in loop iterate through function names为什么 for...in 循环遍历函数名
【发布时间】:2012-10-26 07:11:52
【问题描述】:

在 IE8 中测试一些 JavaScrpt 代码时,我在执行简单的 for..in 循环时遇到了一些奇怪的行为:

var categories = ['for', 'bar', 'steam'];
for(var key in categories) {
    console.log(key);
}

输出:

0
1
2
forEach
map
filter
reduce
indexOf
end

其中包括 Array 原型函数,对吧?这绝对不是它应该工作的方式。这是为什么呢?

顺便说一句,将循环更改为 for (var key=0; key < categories.length, key++) 时它当然可以工作。

【问题讨论】:

标签: javascript for-loop internet-explorer-8


【解决方案1】:

那是因为您可能正在使用扩展 Array.prototype 的库。它不会在其他浏览器中发生的原因是它们已经原生支持这些方法。由于 IE 不支持,所以有一些代码在 JS 中添加,使得方法可以枚举。

这就是为什么您不应该将 for in 与数组一起使用的原因之一。

另一个事实是for in 不保证迭代的顺序,尽管它在大多数浏览器中确实有效,但它被明确地保留为规范未定义的行为。 John Resig 本人针对 chrome http://code.google.com/p/chromium/issues/detail?id=883 提交了一个错误,它已关闭,因为无法修复,因为不需要订购属性

坚持使用标准循环

【讨论】:

  • “虽然它不起作用”是什么意思?它可以工作,但是它枚举了无序的属性,如您所描述的。另外我认为没有“使方法可枚举”的东西,默认情况下,添加到数组中的所有方法都是可枚举的。
  • @Nappy,我不知道你在说什么。我说过,在大多数浏览器中,它确实有效(以正确的顺序迭代)。如果你自己添加属性,它们将是可枚举的,但原生方法是不可枚举的
  • 啊,抱歉这是语言问题,你的意思是……就像“这就是它在大多数浏览器中的工作方式”。你的使用虽然让我很困惑:)
  • @Nappy 你对某事的使用让我感到困惑……我们在 SO 不使用即时消息说话。我仍然不知道你的意思是什么,你不知道“它确实有效”是指以正确的顺序迭代数组?
【解决方案2】:

for..in 用于对象 not 数组。使用常规的for 循环:

for (var i = 0; i < categories.length; i++) {
  console.log(categories[i]);
}

for...in 在您不关心索引时适用于数组,但不建议这样做。您遇到的问题是因为for...in 查找对象的所有属性,包括原型中的属性,这就是为什么建议始终检查属性是否确实在对象中的原因。

for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
        // do something
    }
}

【讨论】:

  • 如果您不想查看继承的属性,建议您有时会这样做。
【解决方案3】:

您似乎使用了一些框架。 迭代数组是不好的方法,因为一些框架向标准原型添加了功能。

 for (var i=0, len=arr.length; i<len; ++i) {

 }

该代码在任何地方都可以使用。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-23
  • 2020-05-22
  • 2020-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多