Defining Properties Using Object.DefineProperty() Javascript

Introduction

In Javascript, an object is the collection of key-value pairs where keys are called properties or attributes. We can define property using dot notation also. We can create an object and property as follows. 

 var book = {};
 book.author = "Rudyard";
 book.subject = "Literature";

Values added using the above assignment can be overwritten, can be deleted and shows up during enumeration means appear in (for...in loop and Object.Keys method). See an example below:

 var book = {};
 book.author = "Rudyard";
 book.subject = "Literature";
 for(var i in book){
  console.log(i); // Prints author and subject both
 }

Using Object.defineProperty

In some cases, we need to define or modify the existing property. This can be achieved using Object.defineProperty() method. We can define some property that will be directly associated with the object, can manipulate the existing property configuration. The method returns the object. We can call this method directly on the Object constructor only. We can't call this on an object instance defined. Using this method, we can control the behavior of the properties. We have more control over the property. 

Syntax

Object.defineProperty(obj, property, descriptor)

How we can control properties?

We can specify metadata which specifies different attributes associated with the property such as writeable, configurable, enumerable or value. These attributes are called data descriptors as they have a value that can be writable or not.
The data descriptors are defined below. You can read about descriptors here.
  • writeable - If the property value can be changed or not using the assignment operator. The default value is false. Conveys whether the property can be assigned a new value or not.
  • configurable - if true we can change the type of the property descriptor or even delete that property from the object. The default value is false.
  • enumerable - if true that property will show up during enumeration of the objects or not. The default value is false.
  • value - The value of the property. The default value is undefined.

Enumerable Property Example

We can see that properties defined using Object.defineProperty() will not appear in for...in  loop and Object.keys method as enumerable is false by default. So we need to make enumerable to true to make them appear in for...in loop.


var book = {};
book.author ="ddsd";
book.price = 100;
Object.defineProperty(book,'a',{
 writable: true,
 enumerable: false // Property a will not appear in for..in loop
});
for(var i in book){
  console.log(i); // Logs author and price
}

If we set enumerable to true then we will get property 'a' also in the for...in loop.

Writable Property Example

We can see how using the writable property we can reassign a new value to a property. Set the writable property to true in the property configuration.

var book = {};
book.author ="Kipling";
Object.defineProperty(book,'a',{
   writable: true, // Sets this to true here
   enumerable: true,
   value: 233
});
book.a = 333; // Can reassign a with 333 as writable is true
for(var i in book){
  console.log(book[i]); // logs Kipling and 333
}

Configurable Property Example

We can see that if true we can change the type of the property descriptor or even delete that property from the object. The default value is false.

var book = {};
book.author ="Kipling";
Object.defineProperty(book,'a',{
    writable: true,
    enumerable: true,
    configurable: true,
    value: 233
});
book.a = 333;
delete book.a; // Can delete property 'a' as configurable is true
for(var i in book){
  console.log(i); // logs only aunthor
}

If we set configurable to false then we will get property 'a' along with property 'author' in the for...in loop.

Access Descriptors
Access descriptors are a pair of the get and set functions. These are objects. The default value for the get and set functions is undefined.
get() - A function that is served as a getter for the property. When the property is being used this function is called without any argument and using this scope sets to the object. The return value is the value of this property.
set()A function that is served as a getter for the property. When the property is assigned this function is called with the argument as the value and with this scope sets to the object. 

Comments