Some notes on enumerable and non-enumerable properties in JavaScript

 •  Filed under javascript

In Javascript enumerable properties are all those which can be iterated with a for…inloop.
Every property has an attribute called. If that is set to true, the property is enumerable, if the attribute is set to false, the property is non-enumerable. When iterating through all properties of an object with a for…in loop, the loop will only iterate over the properties whose enumerable attribute is set to true.
Properties such as length, and valueOf have an enumerable value of false by default, because it is assumed that you won’t want to iterate over those properties when iterating over all your other properties.

Find out whether a specific property is enumerable

In order to detect whether a property is enumerable you can call the propertyIsEnumerable(prop) method on the object, passing the property to be checked.

let obj = {hello: 'world'}; console.log(obj.propertyIsEnumerable('hello')) //'true'

Making properties non-enumerable

To create your own non-enumerable properties, you can use the Object.defineProperty() method:

Object.defineProperty(obj, ‘propName’, { value: ‘propValue, enumerable: false });

This will create a non-enumerable propName property on obj with the value ‘propValue’.

Retrieving all enumerable properties

To get all enumerable properties, both those found directly in the object and those inherited from the prototype chain, use the for…in loop. Note, however, that object created from built-in constructors such as Object, Array or String  inherit non-enumerable properties from those built-in prototypes. So if you declare an an empty array and iterate over it with a for…in, there will be nothing inside the loop since the object only inherited non-enumerable properties.

function Yello(){ 
  this.prop = 'Hi'; 
} 
var obj = []; 
for (o in obj) { 
//nothing inside the loop, since obj only inherited non-enumerable properties 
console.log(o); 
} 
obj = {hello: 'world'}; 
for (o in obj) { 
console.log(o); //['hello'] 
} 
obj = new Yello(); 
obj.there = 'there'; 
for (o in obj) { 
console.log(o); //['prop', 'there'] 
}

JSON.stringify() works by iterating through all enumerable properties of an object (inherited and directly defined).

console.log(JSON.stringify(obj)); // {"prop":"Hi","there":"there"}

Retrieve enumerable properties found directly in an object

To retrieve the set of enumerable properties which were defined directly in an object (no inherited properties), call the keys() method on the object.

let obj = {hello: 'world'}; 
Object.defineProperty(obj, 'propName', { value: 'propValue', enumerable: false }); 
console.log(Object.getOwnPropertyNames(obj)); // [ 'hello']

Only returns ‘hello’, since propName is a non-enumerable property

Retrieve all enumerable and non-enumerable properties found directly in an object

To get all enumerable and non-enumerable properties which were defined directly in an object (no inherited properties) you can use the Object.getOwnPropertyNames() class method.

let obj = {hello: 'world'}; 
Object.defineProperty(obj, 'propName', { value: 'propValue', enumerable: false }); 
console.log(Object.getOwnPropertyNames(obj)); // [ 'hello', 'propName' ]