Javascript for-in循环奇怪的行为

时间:2016-09-09 17:13:16

标签: javascript for-loop for-in-loop

突然间,我看到一种奇怪的行为。 这是一个片段:

// attributesList is an object with properties 0, 1, 2.
for (var j in attributesList) {
   // this loop should run 3 times.
   var attribute = attributesList[j];
}

从上面可以看出,循环应该运行3次。但是由于一些非常奇怪的原因,它被运行了4次。对于最后一次迭代,j ==“seek”的值。

更奇怪的是,这个相同的代码库在另一个git分支上工作(没有变化)。当我从特定的git分支运行它时,似乎只会发生这种情况。

这个神秘的“寻求”财产有任何合理的解释吗? 我尝试过的一件事可能是javascript版本和任何其他版本差异......但这里没有运气。

*已更新*

attributesList是一个对象类型的数组。

1 个答案:

答案 0 :(得分:3)

有问题的对象具有四个可枚举属性。它可能从其原型对象继承seek,这就是为什么你认为它只有三个属性。

您对MikeC的评论增加了重点:

  

当我在运行/调试时评估attributesList时,我没有看到任何名为" seek"

的属性

与您的更新一样:

  

attributesList是一个对象类型的数组。

这告诉我们你的代码库中的某个地方(可能是一个插件),有人非常顽皮,并为Array.prototype添加了一个可枚举的属性。他们可以用各种不同的语法来做到这一点;如果它只是一个属性(seek),它可能是这样的:

Array.prototype.seek = function() {
    // ...
};

这种糟糕的做法,应该让它不可枚举:

Object.defineProperty(Array.prototype, "seek", {
    value: function() {
        // ...
    }
});

但从根本上说,for-in不适用于循环数组。有关如何循环遍历数组,请参阅my other answer here

这个长答案的两个摘录:

使用forEach

attributesList.forEach(function(attribute) {
   // ...
});

或者如果您真的想使用for-in,请添加hasOwnProperty支票:

for (var j in attributesList) {
   if (attributesList.hasOwnProperty(j)) {
      // this loop should run 3 times.
      var attribute = attributesList[j];
   }
}

或当然使用for循环。有关详细信息,请参阅the answer