Defining and Configuring Object Properties in JavaScript

So JavaScript has made it possible for us to interact with property attributes. Now we can make an object property enumerable, set it to read only and even make it configurable. This is possible because of property attributes. 

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:

Let's say we wouldn't anyone to delete the chasis_no property or may be we would want engine_no as just a read-only property. By the way, all properties of an object are both enumerable and configurable by default. JavaScript allows us to interact with object properties and we can do that by calling Object.defineProperty method which takes an object, property name we want to interact with and property descriptor object as parameters. 

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. 

So there are two kinds of property attributes, namely; data properties and accessor property attributes. JavaScript allows us to configure properties, let's consider few scenarios:

  • A JavaScript programmer may want to control whether a property of a certain object should be deleted or not. For example, he may not want to allow deletion of a certain 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]].

Interesting, JavaScript allows us to configure all these property attributes using a method named Object.definedProperty(object, property_name, property_descriptor). So the first parameter is the object, second is the name of the property we want to configure and third is the property descriptor that contains the values of enumerable (configures the internal property [[Enumerable]]), configurable (configures the internal property [[Configurable]]), value (configures the internal property [[Value]]), writable (configures the internal property [[Writable]]), get (configures the internal property [[Get]]) and set (configures the internal property [[Set]]) as shown below.

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.

References: