在Javascript中,“for ... in”不会迭代原型的属性?

时间:2015-11-11 03:15:56

标签: javascript prototype

在MDN(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty)上,我看到了这样的片段:

var buz = {
  fog: 'stack'
};

for (var name in buz) {
  if (buz.hasOwnProperty(name)) {
    console.log('this is fog (' + name + ') for sure. Value: ' + buz[name]);
  }
  else {
    console.log(name); // toString or something else
  }
}

在摘录中,console.log(name); // toString or something else对我来说有点混乱。我了解toStringObject.prototype的属性,buz.toString可以访问此属性。

但是,当我在Chrome中运行代码段时,我没有看到toString属性已打印(console.log),但评论说它应该由for..in进行迭代并打印。

有没有人知道为什么一个原型的属性不能被“for..in”迭代?

2 个答案:

答案 0 :(得分:3)

for x in obj仅迭代对象的可枚举属性(包括原型上的那些属性)。给定的属性可以标记为可枚举或不可。因此,如果for/in正在跳过某些属性,那很可能是因为该属性未配置为可枚举。

请参阅此处的工作演示:http://jsfiddle.net/jfriend00/gyc9gnmj/,其中显示了如何使用for x in obj迭代可枚举属性。

事实上,您可以看到使用以下代码将toString()方法标记为enumerable: false

function log(x) {
    document.write(JSON.stringify(x));
}

var buz = {
  fog: 'stack'
};

log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(buz), "toString"));

答案 1 :(得分:0)

为了延续jfriend00已经回答的内容,JavaScript中对象的数据属性有四个属性,即[[configurable]],[[enumerable]],[[writable]]和[[ value]]所有这些都设置为前三个默认值为true,最后默认值为undefined。

假设存在需要避免在for-in循环中不返回属性值的需要。你可以写成

var car = {};
Object.defineProperty(car, 'name',{
enumerable : false,
value : 'BMW'
});