Enumerability is one of the three attributes of a property: writability, enumerability, and configurability. My questions are:
pop
and push
properties being non-enumerable?Objects can have properties that don't show up when iterated through the particular object using Object. keys() or for...in loop. Those type of properties are called as non-enumerable properties.
Enumerable properties are those properties whose internal enumerable flag is set to true, which is the default for properties created via simple assignment or via a property initializer. Properties defined via Object.
An enumerable property in JavaScript means that a property can be viewed if it is iterated using the for…in loop or Object. keys() method. All the properties which are created by simple assignment or property initializer are enumerable by default.
Symbol properties are never iterated by a for...in loop, therefore they can be considered non-enumerable (2).
I think the main benefit is to be able to control what shows up when enumerating an object's properties, such as for in
or Object.keys()
.
MDN explains it well with Object.defineProperty
: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty
So normally, when people want to add a method to Object
, such as a polyfill for some method not supported in old browsers, they modify the .prototype
. But that makes the property enumerable and messes up what is returned in loops/keys collection (without using .hasOwnProperty
...which not everyone uses).
So instead of something like:
Object.prototype.myMethod = function () { alert("Ahh"); };
you could use Object.defineProperty
to explicitly say to have it not be enumerable:
Object.defineProperty(Object.prototype, 'myMethod', { value: function () { alert("Ahh"); }, enumerable: false });
That way, for example when you use for (var key in obj)
, "myMethod" won't be an item enumerated, and you won't have to worry about using .hasOwnProperty
. The main problem with this is that some browsers don't support it of course: http://kangax.github.com/es5-compat-table/ and that not all libraries/code use it, so you can't always rely on external libraries/code to do use correctly and all the time.
You can access a non-enumerable property at any time you want, it just won't show up when enumerating the object's properties - that's the main point.
And I do believe that all "predefined" properties of objects are non-enumerable. By that, I really only mean native properties, not necessarily inherited or created. So with your example, pop
and push
will not be enumerated over, but Array.prototype.indexOf
will be if it is created as a polyfill on an old browser that doesn't support that method...which of course, can be avoided by using Object.defineProperty
like my example above. Another example is the length
property, which is not enumerated over.
Here's an example in general: http://jsfiddle.net/aHJ3g/
The use and definition of Object.keys
is important: "Returns an array of a given object's own enumerable properties, in the same order as that provided by a for-in
loop (the difference being that a for-in
loop enumerates properties in the prototype chain as well)." - from MDN - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With