【问题标题】:Does JavaScript's for in loop iterate over methods?JavaScript 的 for in 循环会遍历方法吗?
【发布时间】:2011-02-02 07:05:47
【问题描述】:

在 yuiblog 上的 article 中,Douglas Crockford 说 for in 语句将遍历对象的方法。为什么下面的代码不产生 ["a", "b", "c", "d", "toString"]? .toString() 和其他方法不是 my_obj 的成员吗?

Object.prototype.toString = function(){return 'abc'}
Object.prototype.d = 4;

my_obj = {
    'a':1,
    'b':2,
    'c':3
}

a = []
for (var key in my_obj) {
    a.push(key)
}

console.log(a) // prints ["a", "b", "c", "d"]

【问题讨论】:

    标签: javascript for-in-loop


    【解决方案1】:

    for..in 迭代用户定义的属性。如果您将代码更改为:

    Object.prototype.foo = function() { return 'abc'; };
    

    然后

    console.log(a);
    

    将输出:

    ["a", "b", "c", "foo", "d"]
    

    正如Chetan Sastry 指出的那样,toString 被区别对待,因为它是一个内置的原生属性。

    【讨论】:

      【解决方案2】:

      所有用户定义的属性都是可枚举的,包括从原型继承的属性。内置的本机属性不是。 toString() 就是其中之一。看这里https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Statements/For...in

      编辑:我对的解释“但是,循环将遍历所有用户定义的属性(包括任何覆盖内置属性的属性)”直接在对象中覆盖的变为可枚举的。不是原型本身的覆盖。这意味着:

      var my_obj = {a: 1, b: 2, c: 3};
      my_obj.toString = function() {return 'abc';};
      
      a = []
      for (var key in my_obj) {
          a.push(key)
      }
      
      console.log(a) // prints ["a", "b", "c", "toString"]
      

      【讨论】:

      • 是的,Object.prototype.toString.propertyIsEnumerable() == false
      • 从您链接的文档中:“for...in 循环不会遍历内置属性。这些包括对象的所有内置方法,例如 String 的 indexOf 方法或 Object 的 toString 方法. 但是,循环将遍历所有用户定义的属性(包括任何覆盖内置属性的属性)。”如果在我的示例中 .toString() 没有被覆盖,为什么文档会说“包括任何覆盖内置属性的内容”?
      • @hekevintran:更新了我的答案。
      • 我明白了。感谢您的澄清。
      猜你喜欢
      • 2020-11-17
      • 1970-01-01
      • 1970-01-01
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多