Our task is to create a Person constructor which takes two parameters: firstName and lastName. Our object will expose four attributes: firstName, lastName, fullName and species. The first three will react to changes, and the last one species will have a constant value of
'human'. Example below:
How to solve it?
Here is the part where Object.defineProperty comes to the rescue. It is a method of ECMAScript 5, and it’s used to define or override the attributes of an object. It accepts as a parameter the object to be modified. The second parameter is the name of the key. The third is the ‘description’ attribute. The ‘description’ field is an object that provides us with the following fields:
- configurable – true if and only if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object. Defaults to false.
- enumerable – true if and only if this property shows up during enumeration of the properties on the corresponding object. Defaults to false.
A data descriptor also has the following optional keys:
- writable – true if and only if the value associated with the property may be changed by an assignment operator. Defaults to false.
- get – A function which serves as a getter for the property. Whatever the function returns will be used as the value of the property. When it is
undefinedthe getter behavior is ignored. Defaults to undefined.
- set – A function which serves as a setter for the property, or undefined if there is no setter. The function will receive one argument with the new value being assigned to the property. Defaults to undefined.
Let’s check now how to solve this task by building the
Person constructor – which for now will have 3 fields: firstName, lastName and species. The fullName field will be implemented later. As we read in the documentation of
Object.defineProperty we can add a field to the object and in descriptor set the
writable attribute to false, which will allow us to protect the value from being overwritten. Let’s see how this works in practice:
We have now created an attribute which cannot be overwritten. Congratulation on our first success.
Let’s move on to the second part of our task. We need to define a fullName attribute which always will return the current name. Also, we want to be able to set the value of fullName and have the lastName and firstName attributes update accordingly. By using get and set we can define what will happen with the object and what will be returned. Let’s solve this now and see how it works in practice:
Object.defineProperty is supported by all modern browsers – Internet Explorer 8 supports
Object.defineProperty only for DOM objects. It is worth mentioning that Firefox has performance problems but this is only noticeable when we have more than 100k objects.
Good to know
This is just one of the many hidden gems of ES5. I encourage you to read the documentation of many other interesting methods like