JS Tip of the Day: What Uses enumerable?

What Uses enumerable?
Level: Intermediate

When a property is enumerable, it means it will appear in normal property enumeration, which is when you go through the properties of an object in, for example, a for...in loop. As a for...in goes over the keys of an object, it will ignore non-enumerable properties completely. To get or set this characteristic using Object.getOwnPropertyDescriptor() and Object.describeProperty().

let mixed = {
    tapes: ['summer of 1969'],
    emotions: ['happy', 'sad'],
};
Object.defineProperty(mixed, 'emotions', { enumerable: false });

for (let key in mixed) {
    console.log('Found key:', key);
}
/* logs
Found key: tapes
*/

Not everything checks properties for being enumerable. There are certain APIs which skip that check and will recognize non-enumerable properties along with the enumerable ones. The following is a list of statements and APIs that do and do not respect enumerable.

  • Recognizes enumerable:

    • 'for…in`
    • 'JSON.stringify`
    • 'Object.entries`
    • 'Object.keys`
    • 'Object.values`
    • 'Object.assign`
    • Object Spread (...)
  • Ignores enumerable:

    • 'Object.getOwnPropertyDescriptors`
    • 'Object.getOwnPropertyNames`
    • 'Object.getOwnPropertySymbols`
    • 'Reflect.ownKeys`

You’d most commonly be using those listed under recognizing enumerable. Those that don’t largely exist as alternatives to others that would allow you to get to the non-enumerables when you’d explicitly want them.

let mixed = {
    tapes: ['summer of 1989'],
    emotions: ['happy', 'sad'],
};
Object.defineProperty(mixed, 'emotions', { enumerable: false });

console.log(Object.keys(mixed)); // ['tapes']
console.log(Reflect.ownKeys(mixed)); // ['tapes', 'emotions']

You may notice that for...of is not in this list. That’s because for...of is dependent on the iterable its looping over. That iterable determines what is provided in the loop. Arrays are one of the more common iterables that might be used with for...of. Their iterators do not look at object properties or their enumerable values, rather they go through an array’s indexed property values from 0 up to the array’s length whether or not they even exist, let alone enumerable.

More info: