【问题标题】:JavaScript: Why does the "for in" loop pick variables from __proto__?JavaScript:为什么“for in”循环从 __proto__ 中选择变量?
【发布时间】:2019-05-16 12:24:17
【问题描述】:

我在Object的原型中添加了一个方法trigger

Object.prototype.trigger = function() {
    //  ...
    return this;
};

然后有一个“for in”循环:

var obj = { 4: 15, 10 : 41, 11 : 46, 12 : 51, 20 : 74 }
for( item in obj ) {
    foo( obj[item] );
}

但是这个循环有 6 次迭代而不是 5 次。最后一次迭代是带键的:

item = "trigger"

为什么循环会遍历对象的__proto__ 部分?

【问题讨论】:

标签: javascript for-loop prototype


【解决方案1】:

for...in 遍历所有对象属性,而不区分对象本身或其任何祖先的属性。

为了只检查对象本身定义的属性,您可以使用Object.prototype.hasOwnProperty

const obj = { 4: 15, 10 : 41, 11 : 46, 12 : 51, 20 : 74 }
for( item in obj ) {
  if(obj.hasOwnProperty(item) {
    foo( obj[item] );
  }
}

// will ignore the trigger func and everything else defined on any prototype

【讨论】:

    【解决方案2】:

    for..in 迭代原型链上任意位置的所有可枚举属性。如果您想让trigger 不可枚举,因此它不会与for..in 一起迭代,请改用Object.defineProperty,这会使定义的属性默认为不可枚举:

    Object.defineProperty(Object.prototype, 'trigger', { value:  function() {
        
    }});
    var obj = { 4: 15, 10 : 41 }
    for( item in obj ) {
        console.log(item);
    }

    【讨论】:

    • 我不确定。我认为您仍然应该致电Object.hasOwnProperty,可能还有其他代码扩展原型。
    【解决方案3】:

    另一种方法是使用 Object.keys 代替:

    Object.prototype.trigger = function() {
        return this;
    };
    
    var obj = { 4: 15, 10 : 41, 11 : 46, 12 : 51, 20 : 74 }
    
    Object.keys(obj).forEach(function(item) {
        console.log( "Key: " + item + ", value: " + obj[item] );
    });

    【讨论】:

      【解决方案4】:

      这是我前段时间遇到数组的一个错误。因为数组也是对象,您可以向下迭代到原型中,所以不要对数组使用for..in。您的示例特定于导致此问题的对象。相反,使用标准 for 来遍历对象的项目。这样,您就可以为您想要实现的目标提供更清洁、更安全的实现,而不是使用主要用于实现反射的 defineProperty 或 hasOwnProperty。

      for (var i = 0; i < Object.values(obj).length; i++){
        console.log(i + ': ' + Object.values(obj)[i]);
        //foo( Object.values(obj)[i] );
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-12
        • 2013-09-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多