Non-enumerable properties in JavaScript
• http://joshua.poehls.me/2013/non-enumerable-properties-in-javascript/
It isn’t very common in the wild but JavaScript (as of ES5) does support non-enumerable properties.
That is to say, objects can have properties that don’t show up when you do a for...in
loop over the object or use Object.keys()
to get an array of property names.
I spent way too long tonight figuring out why a property was not being
included in the JSON.stringify()
output because I didn’t remember that this was possible. You see, stringify()
works by enumerating the object’s properties.
So it makes sense that non-enumerable properties would be ignored.
Let me explain.
var person = { age: 18 }; person.name = 'Joshua'; person['color'] = 'Red'; Object.keys(person); // ['age', 'name', 'color']
That is how you typically create and assign properties. We know that they are enumerable because they show up when you call Object.keys(person)
.
To create a non-enumerable property we have to use Object.defineProperty()
. A special method for creating properties on an object.
var person = { age: 18 }; Object.defineProperty(person, 'name', { value: 'Joshua', enumerable: false }); person.name; // 'Joshua' Object.keys(person); // ['age']
See there? Our name
property didn’t show up because it wasn’t enumerable. Consequently, doing JSON.stringify(person)
would not include the name
property either.
Hopefully this will help you the next time a property is missing from your stringified object and you can’t figure out why. Good luck!
Bonus!
Object.defineProperty()
is also how you create read-only properties. Didn’t know you could do that in JavaScript? Time to study up!