I am Joshua Poehls. Say hello Archives (not so) silent thoughts

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!

⦿