Object properties and property descriptor
So object has properties and we can set the state of those properties using fields (e.g. value, writable, enumerable, get, set, and configurable) of property descriptor object. We can see how we can access fields of property descriptor object below:
So here is an object:
Data and accessor properties
There are data properties and accessor properties. Data property is a value which can be read, written to, configured and and even enumerated. Whereas accessor properties define get and set functions that are called when property is read or written to, respectively. If we look at the following code:
'wife_enabled' is the data property whereas 'name' is being used as the accessor property.
- Let's say a User class is defined with two properties; username and password. Furthermore, let's say I don't want to make the password property enumerable, that is, I don't want the password property to appear when someone is enumerating User properties.
- Let's say a Car class has a property named chassis number and we want to make it a read only property, i.e., no one can write it. How do we go about it?
Using property attributes to change state of properties
We can make all this happen using property attributes (and they can be set using property descriptor object and we will shortly see an example), and those are:
[[Enumerable]]: Allows us to make a property enumerable, i.e., if it's false, then this property won't show up when the object's properties are enumerated using a for-in loop. Its default value is set to false.
[[Configurable]]: It defines whether the property can be deleted or if it can be changed to accessor property . If it's set to false, then property cannot be deleted and it cannot be changed to accessor property. Default value of this attribute is set to false.
[[Value]]: The actual value of property is stored in this. Default value of this attribute is set to undefined.
[[Writable]]: Allows us to configure whether we can write to a property. If it's set to false we cannot alter the property's [[Value]] attribute. So, for example, if we want to create a read only property we should set writable attribute to false. Default value of this attribute is false.
[[Get]]: This contains the Getter function which you can define to do some processing while reading the value. [[Get]] is exclusively used for accessor properties. Default value of this attribute is undefined.
[[Set]]: As the name suggests, this contains the Setter function which you can define to do some processing while setting the value. [[Set]] is exclusively used for accessor properties. Default value of this attribute is undefined.
So, both [[Enumerable]] and [[Configurable]] are common to both data and accessor properties, whereas, data properties have two additional attributes, namely; [[Value]] and [[Writable]]. Accessor properties have two more attributes and those are [[Get]] and [[Set]].
Hopefully, the following code will clear things up:
There, however, is one caveat we should keep in mind. If we don't specify the value of property attributes when we are trying to configure a property then they default to false. So let's look at some code.
In the above example, we have not given the values of writable, and configurable attributes when we called Object.defineProperty() so they will default to false. So this is something important which needs to be kept in mind while configuring property attributes.