Because of the dynamic nature of JavaScript, people are able to modify freely build-in objects (a technique known as monkey-patching) and change their behavior, which can eventually cause different side-effects and bugs.
In ECMAScript 3 an object property definition consisted only of value, name and context. There was no way to manage the mutable state of a property.
ECMAScript 5 introduced a new mechanisms for managing and restriction of what can be done to an object member. A new .defineProperty() and .defineProperties() methods were implemented. As you can most certainly guess, they define new object properties, just like the dot-notation property definition with one big difference - these methods can control the characteristics of the property. By characteristics I mean the ability to change the value of the property (writable), the ability to change the characteristics of the property once defined (configurable) and the ability to determines whether or not the property is enumerated (shown) with all of the other members (enumerable).
What enumerable exactly means
It simply means that the property will show up if you iterate over the object using for..in loop or Object.keys. Let's look at one simple example:
As you can see enumerable is set to true. This is because every new property is enumerable by default (enumerable set to true). There is an exception to this rule, but we will look at it later.
Now, let's extend your object with one more property:
As you can see, the enumerable flag is set to true by default. But what if we want to create a new property which is not enumerable. We can do this with the help of the Object.defineProperty() method:
Now we have a new property named flameWarTopic with a value of "Angular2 vs ReactJS". To check if an object's property is enumerable or not, we can use the build-in Object method propertyIsEnumerable():
There is one really important point you need to remember - properties, created with defineProperty() method have an enumerable flag set to false by default if not explicitly set to true.
This is were the things get a little bit messy. The defineProperty() method accepts 3 parameters:
The object on which to define the property.
The name of the property to be defined or modified.
The descriptor for the property being defined or modified.
The descriptor object is where we define the characteristics of the property. Let's see what happens if you don't explicitly set the enumerable flag:
Kleo Petrov
Professional human being for 29 years
Because of the dynamic nature of JavaScript, people are able to modify freely build-in objects (a technique known as monkey-patching) and change their behavior, which can eventually cause different side-effects and bugs.
In ECMAScript 3 an object property definition consisted only of value, name and context. There was no way to manage the mutable state of a property.
ECMAScript 5 introduced a new mechanisms for managing and restriction of what can be done to an object member. A new
.defineProperty()and.defineProperties()methods were implemented. As you can most certainly guess, they define new object properties, just like the dot-notation property definition with one big difference - these methods can control the characteristics of the property. By characteristics I mean the ability to change the value of the property (writable), the ability to change the characteristics of the property once defined (configurable) and the ability to determines whether or not the property is enumerated (shown) with all of the other members (enumerable).What enumerable exactly means
It simply means that the property will show up if you iterate over the object using
for..inloop orObject.keys. Let's look at one simple example:const obj = { purposeOfLife: 42, } Object.getOwnPropertyDescriptor(obj, 'purposeOfLife')Object.getOwnPropertyDescriptor()returns an object with the characteristics of the property. In our case it will return:{ value: 42, writable: true, enumerable: true, configurable: true }As you can see
enumerableis set totrue. This is because every new property is enumerable by default (enumerableset to true). There is an exception to this rule, but we will look at it later.Now, let's extend your object with one more property:
obj.favouriteWebsite = 'Hashnode' Object.getOwnPropertyDescriptor(obj, 'favouriteWebsite ') // { // value: "favouriteWebsite ", // enumerable: true, // writable: true, // configurable: true // }As you can see, the
enumerableflag is set to true by default. But what if we want to create a new property which is not enumerable. We can do this with the help of theObject.defineProperty()method:Object.defineProperty(obj, 'flameWarTopic', { value: 'Angular2 vs ReactJS', configurable: true, writable: false, enumerable: false });Now we have a new property named
flameWarTopicwith a value of"Angular2 vs ReactJS". To check if an object's property is enumerable or not, we can use the build-in Object methodpropertyIsEnumerable():const isEnumerable = obj.propertyIsEnumerable('flameWarTopic') // falseThere is one really important point you need to remember - properties, created with
defineProperty()method have anenumerableflag set to false by default if not explicitly set to true.This is were the things get a little bit messy. The
defineProperty()method accepts 3 parameters:The descriptor object is where we define the characteristics of the property. Let's see what happens if you don't explicitly set the
enumerableflag:Object.defineProperty(obj, 'last', { value: '', configurable: true }); const lastEnumerable = obj.propertyIsEnumerable('last'); // falseIn the example above,
lastEnumerablejust returns false. This is because by default, values added using Object.defineProperty() are immutable.The only thing left is to see an example of the
for..inloop, so here it is:for (let key in obj) { console.log(key) }The result will be the following:
"purposeOfLife" "favoriteWebsite"Our
objhave 4 properties -purposeOfLife,favouriteWebsite,flameWarTopicandlast, but only theenumerableproperties will show up.Further reading
I've combined the examples in a single jsbin, which you can check and experiment with - examples.