不可枚举的属性出现在 for..在 Chrome 中循环



A for - in循环将遍历对象的所有可枚举属性,甚至是原型链中的属性。函数hasOwnProperty可以筛选出原型链中的那些可枚举属性。最后,函数propertyIsEnumerable可以区分对象的可枚举属性。

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

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

但是,在Chrome上,上述内容打印了很多属性名称。

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

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

你可以看到更多关于window对象实际上是什么的证据 window.constructor ,这将显示它是由

function Window() { [native code] }

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

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

这样做仍会返回一个包含 30 多个属性的数组。把它归结为铬的奇怪之处!

编辑:通过一些进一步的测试,我找到了Chrome的正确方法,以理解window的可枚举属性

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) for...inObject.getOwnPropertyNames 的属性列表分别为 423 和 454。

Chrome很奇怪:

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

它提供了大约 30 个属性,而另一种方式为 450 个,在铬中。

最新更新