for
-in
循环将遍历对象的所有可枚举属性,甚至包括原型(prototype)链中的那些属性。函数hasOwnProperty
可以过滤掉原型(prototype)链中的那些可枚举的属性。最后,函数propertyIsEnumerable
可以区分对象的可枚举属性。
因此,以下脚本不应打印任何:
for(a in window)
if(window.hasOwnProperty(a) && !window.propertyIsEnumerable(a))
console.log(a);
但是,在Chrome上,上面显示了许多属性名称。
为什么
for
-in
循环和propertyIsEnumerable
在可枚举方面相互矛盾? 最佳答案
可悲的事实是JavaScript引擎不一样。尽管符合ES5的引擎会尽职地尊重其属性的可枚举性,但是window
是主机对象,正如上面的pimvdb和Felix所指出的那样,并不依赖于ES5的规则。
您可以在window
中看到更多有关window.constructor
对象实际上是什么的证据,这将显示它是从构造的
function Window() { [native code] }
因此,我们没有真正的方法来确定为什么某些属性是可枚举的(根据Chrome),而其他属性并非来自JavaScript运行时。
但是,您仍然可以通过查看
window
来查看Chrome浏览器不一致的Object.keys(window)
可枚举属性的完整状态,根据its MDN article,它会“返回在给定对象上找到的所有自己的可枚举属性的数组”。这样做仍然会返回一个包含30多个属性的数组。用粉笔来形容Chrome的怪异之处!
编辑:经过一些进一步的测试,我找到了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...in
的属性列表分别为423和454。关于javascript - 不可枚举的属性出现在Chrome中的for ... in循环中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12146473/