13

A for-in循环将遍历对象的所有可枚举属性,即使是原型链中的属性。该函数hasOwnProperty可以过滤掉原型链中的那些可枚举属性。最后,该函数propertyIsEnumerable可以区分对象的可枚举属性。

因此,以下脚本不应打印任何内容

for(a in window)
    if(window.hasOwnProperty(a) && !window.propertyIsEnumerable(a))
        console.log(a);

然而,在 Chrome 上,上面打印了很多属性名称。

为什么for-in循环并propertyIsEnumerable在可枚举方面相互矛盾?

4

2 回答 2

3

可悲的事实是 JavaScript 引擎并不相同。虽然符合 ES5 的引擎会尽职尽责地尊重其属性的可枚举性,window但正如上面 pimvdb 和 Felix 所指出的,它是一个宿主对象,并且不受 ES5 规则的约束。

您可以看到更多关于window对象实际存在的证据window.constructor,这将表明它是由

function Window() { [native code] }

因此,我们无法确定为什么某些属性是可枚举的(根据 Chrome),而其他属性不是来自 JavaScript 运行时。

但是,您仍然可以window通过查看其 MDN 文章“返回在给定对象上找到的所有自己的可枚举属性的数组”Object.keys(window)来查看 Chrome 不一致的可枚举属性的完整状态。

这样做仍然会返回一个包含 30 多个属性的数组。把它归结为 Chrome 的陌生感!

编辑:通过一些进一步的测试,我找到了让 Chrome 理解window's enumerable properties的正确方法

Object.keys(window).filter(function(prop) {
  return window.hasOwnProperty(prop) && !window.propertyIsEnumerable(prop);
});

在 Chrome 中,用于枚举的候选属性列表似乎for...in不是由返回的Object.keys,但实际上更接近于Object.getOwnPropertyNames哪个列表可枚举和不可枚举的属性。然而,即使这样也不一致。在我的测试中,和分别window.hasOwnProperty(prop) && !window.propertyIsEnumerable(prop)为 423 和 454的属性列表。for...inObject.getOwnPropertyNames

于 2012-09-15T06:08:22.883 回答
0

铬很奇怪:

for(a in window)
    if(window.hasOwnProperty(a) && window.propertyIsEnumerable(a))
        console.log(a);

与 chrome 中的 450 个属性相比,它提供了大约 30 个属性。

于 2012-08-27T17:27:48.430 回答