Search code examples
javascriptenumerable

What does enumerable mean?


I was directed to MDN's for..in page when it said, "for..in Iterates over the enumerable properties of an object."

Then I went to the Enumerability and ownership of properties page where it said "Enumerable properties are those which can be iterated by a for..in loop."

The dictionary defines enumerable as countable, but I can't really visualize what that means. Could i get an example of something being enumerable?


Solution

  • An enumerable property is one that can be included in and visited during for..in loops (or a similar iteration of properties, like Object.keys()).

    If a property isn't identified as enumerable, the loop will ignore that it's within the object.

    var obj = { key: 'val' };
    
    console.log('toString' in obj); // true
    console.log(typeof obj.toString); // "function"
    
    for (var key in obj)
        console.log(key); // "key"
    

    A property is identified as enumerable or not by its own [[Enumerable]] attribute. You can view this as part of the property's descriptor:

    var descriptor = Object.getOwnPropertyDescriptor({ bar: 1 }, 'bar');
    
    console.log(descriptor.enumerable); // true
    console.log(descriptor.value);      // 1
    
    console.log(descriptor);
    // { value: 1, writable: true, enumerable: true, configurable: true }
    

    A for..in loop then iterates through the object's property names.

    var foo = { bar: 1, baz: 2};
    
    for (var prop in foo)
        console.log(prop); // outputs 'bar' and 'baz'
    

    But, only evaluates its statement – console.log(prop); in this case – for those properties whose [[Enumerable]] attribute is true.

    This condition is in place because objects have many more properties, especially from inheritance:

    console.log(Object.getOwnPropertyNames(Object.prototype));
    // ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", /* etc. */]
    

    Each of these properties still exists on the object:

    console.log('constructor' in foo); // true
    console.log('toString' in foo);    // true
    // etc.
    

    But, they're skipped by the for..in loop because they aren't enumerable.

    var descriptor = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor');
    
    console.log(descriptor.enumerable); // false