Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-enumerable properties appear in for...in loop in Chrome

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?

like image 737
Randomblue Avatar asked Aug 27 '12 17:08

Randomblue


1 Answers

The sad fact is that JavaScript engines are not the same. While ES5 conforming engines will dutifully respect the enumerability of their properties, window is 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 window object actually is in window.constructor, which will show it as being constructed from

function Window() { [native code] }

As 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 window enumerable properties by looking at Object.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 properties

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

It would seem that in Chrome, the candidate list of properties for enumeration by for...in is NOT what is returned by Object.keys, but actually much closer to Object.getOwnPropertyNames which lists enumerable and non-enumerable properties. However, even that is inconsistent. The list of properties that are window.hasOwnProperty(prop) && !window.propertyIsEnumerable(prop) come out to 423 and 454 for for...in and Object.getOwnPropertyNames, respectively, in my testing.

like image 66
Aintaer Avatar answered Nov 01 '22 08:11

Aintaer