在Javascript中,“for...in”不会遍历原型属性吗?

3

我在 MDN(https://developer.mozilla.org/zh-CN/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"迭代的想法?

1
Object.prototype.toString 是一个不可枚举的属性。 - Bergi
2个回答

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"));


0

为了进一步阐述jfriend00已经回答的内容,JavaScript中对象的数据属性有四个属性,分别是[[configurable]]、[[enumerable]]、[[writable]]和[[value]],其中前三个的默认值为true,最后一个的默认值为undefined。

假设存在这样的需求,您希望在for-in循环中避免返回某个属性的值。您可以编写如下代码:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接