Javascript properties are enumerable, writable and configurable

November 3, 2014 9:30 am 17 comments

Objects are one of the main parts of Javascript. JS syntax for Objects is really concise and easy to use, so we are constantly creating objects and using them as hashmaps effortlessly.

But, do you know that all the object properties in the example above are enumerable, writable and configurable? I mean:

  • Enumerable: I can access to all of them using a for..in loop. Also, enumerable property keys of an object are returned using Object.keys method.
  • Writable: I can modify their values, I can update a property just assigning a new value to it: ob.a = 1000;
  • Configurable: I can modify the behavior of the property, so I can make them non-enumerable, non-writable or even non-cofigurable if I feel like doing so. Configurable properties are the only ones that can be removed using the delete operator.

I bet that you knew about the two first features of Object‘s properties, but there are less developers that know that they can create and update them to be non-enumerable or immutable using the Object‘s method called defineProperty.

I reckon that the syntax is not as friendly as usual one, but having this kind of properties can be really handy for some purposes. The object that define the property is called descriptor, and you can have a look at the descriptor of any property using Object.getOwnPropertyDescriptor method.

It is funny that the default option values for Object.defineProperty are completely the opposite to the ones applied when adding a property by assigment: The default property by assignment is non-enumerable, non-writable and non-configurable.

It is also possible to define the properties on object creation if you instantiate it using the method Object.create( prototype, properties ). It accepts an object with property descriptors as the second parameter, and it can be used as follows

Object’s non-enumerable properties

As I said before, enumerable properties are accessible using for...in loops, so, non-enumerable ones aren’t. Basically, non-enumerable properties won’t be available using most of the functions that handle Objects as hashmaps.

  • They won’t be in for..in iterations.
  • They won’t appear using Object.keys function.
  • They are not serialized when using JSON.stringify

So they are kind of secret variables, but you can always access to them directly.

Since this kind of properties are not serialized, I found them really useful when handling data model objects. I can add handy information to them using non enumerable properties.

Can you think how useful can this be to create a ORM library for example?

In case that you need to know all properties in an object, enumerable and non-enumerable ones, the method Object.getOwnPropertyNames returns an array with all the names.

Object’s non-writable properties

While the world waits for ES6 to finally arrive with the desired const statement, non-writable properties are the most similar thing to a constant that we have in Javascript. Once its value is defined, it is not possible to change it using assignments.

As you can see, the assignment didn’t affect the value of ob.B property. You need to be careful, because the assignment always returns the value assigned, even if the property is non-writable like the one in the example. In strict mode, trying to modifying a non-writable property would throw an TypeError exception:

It is also needed to keep in mind that if the non-writable property contains an object, the reference to the object is what is not writable, but the object itself can be modified yet:

If you want to have a property with an completely non-writable object, you can use the function Object.freeze. freeze will make impossible to add, delete or update any object’s property, and you will get a TypeError if you try so in strict mode.

Object’s non-configurable properties

You can update the previous behaviors of the properties if they are defined as configurable. You can use defineProperty once and again to change the property to writable or to non-enumerable. But once you have defined the property as non-configurable, there is only one behaviour you can change: If the property is writable, you can convert it to non-writable. Any other try of definition update will fail throwing a TypeError.

An important thing to know about the non-configurable properties is that they can’t be removed from the object using the operator delete. So if you create a property non-configurable and non-writable you have a frozen property.

Conclusion

Object.defineProperty was introduced with ES5, and you can start using it right now, it is supported by all modern browsers, including IE 9 ( and even IE 8, but only for DOM objects ). It is always fun to play with javascript basics in a different way that we are used to, and it is easy to learn new stuff just observing how javascript core objects work.

Object.defineProperty also give us the chance of creating customized getters and setters for the properties, but I won’t write about that today. If you want to learn more, have a look at the always amazing Mozilla’s documentation.

 

javi

Let’s push your website a bit further

My name is Javier Márquez and I have more than 10 years of web programming and web designing experience. If you have a difficult development to complete, maybe you can stop by and see what I can do for you. You can find me on and Twitter.

17 Comments - Leave yours

  • Nacho

    O M G ! I have worked with javascript from 3 years and i had not idea of that stuff!! I love it! Thanks for the post Javier! :)

  • Simone

    I’m glad you mentioned the customized getters and setters; it’s exactly what I was looking for! Thanks!

  • sonvu.ae

    Great works! I learned alot from your writes :)

  • Aravind

    Well written article. Nice !
    I didn’t know we could set enumerable to false on an object property to stop it from appearing when we do JSON.stringify This would be useful for my data model

  • bl4de

    Good post, I’ve always wondering why Object methods like these arent’s so popular :)

  • Surendra

    Thanks for explaining this with examples. It is a really helpful article.

  • sarang

    your explanation is awesome . i own software development company http://www.clickmind.in and i will also pass this to my employee.

  • shikhar

    Awesome write up man!! loved it. most of the time mozilla’s documentation confuses me :-p

  • Joaquín

    Awesome post! I’ve been working with JavaScript for a while and I didn’t know properties can be configured.

  • Pedro

    Is it possible for a property to be non-enumerable but writable? I want hidden property that I can’t iterate through.

  • Nice post!

Leave a reply


contact meAnything related to web development like javascript and CSS to create responsive designs, or PHP and node.js to make your website work properly, is my pleasure. If you have an interesting project in mind, I can help to make it real.