A for–in loop will go through all enumerable properties of an object, even those in the prototype chain. The function hasOwnProperty can filter out those enumerable properties that are in the prototype chain. Finally, the function propertyIsEnumerable can discriminate the enumerable properties of an object.
Therefore, the following script should not print anything:
for(a in window)
if(window.hasOwnProperty(a) && !window.propertyIsEnumerable(a))
console.log(a);
On Chrome, however, the above prints a lot of property names.
Why do the for–in loop and propertyIsEnumerable contradict each other regarding enumerables?
The sad fact is that JavaScript engines are not the same. While ES5 conforming engines will dutifully respect the enumerability of their properties,
windowis a host object, as pointed out by pimvdb and Felix above, and not beholden to the rules of ES5.You can see more evidence of what
windowobject actually is inwindow.constructor, which will show it as being constructed fromAs such, we have no real way of determining why certain properties are enumerable (according to Chrome), and others are not from within the JavaScript runtime.
However, you can still see the full state of Chrome’s inconsistent
windowenumerable properties by looking atObject.keys(window)which according to its MDN article, “returns an array of all own enumerable properties found upon a given object.”Doing so still returns an array of 30-odd properties. Chalk it up to Chrome strangeness!
EDIT: With some further testing, I found the proper way for Chrome to make sense as to
window‘s enumerable propertiesIt would seem that in Chrome, the candidate list of properties for enumeration by
for...inis NOT what is returned byObject.keys, but actually much closer toObject.getOwnPropertyNameswhich lists enumerable and non-enumerable properties. However, even that is inconsistent. The list of properties that arewindow.hasOwnProperty(prop) && !window.propertyIsEnumerable(prop)come out to 423 and 454 forfor...inandObject.getOwnPropertyNames, respectively, in my testing.