Controlling Object property using special flags
Tags: javascript, object, configure, firstpost
Published: 2020-03-20 12:44:32

An Object is a collection of key/value pairs. Apart from value an 
object property have speacial flags to configure.
 
  1. Writable:  If  false value can not be upadated.
  2. Enumerable: If false property won't be listed in the loop.
  3. Configurable: If false property can't be deleted.

We will use two methods to get and set the flags:

i) Object.getOwnPropertyDescriptor // To get property description
```javascript 
Object.getOwnPropertyDescriptor(obj, 'propertyName');

/* property descriptor:
{
  "value": propertyValue,
  "writable": Boolean,
  "enumerable": Boolean,
  "configurable": Boolean
}
*/
```


ii) Object.defineProperty  // To create/update the property value and flags


```javascript
Object.defineProperty( obj, 'propertyName', 
   {  value: propertyValue, 
      writable : Boolean, 
      enumerable : Boolean,
      configurable: Boolean
    }
 ) 
```

In the next blog, We will use the above method to make an object property Non-writable, Non-Enumerable and non-Configurable.

By Default all the flags are set to true.

```javascript   
let person = { firstName: "john", lastName: "kumar" };

Object.getOwnPropertyDescriptor(person, "firstName");
 /* { 
    value: "john", 
    writable: true, 
    enumerable: true, 
    configurable: true
  }

*/
Object.getOwnPropertyDescriptor(person, "lastName");
 /* { 
    value: "kumar", 
    writable: true, 
    enumerable: true, 
    configurable: true
  }

*/
```

##1. Non-Writable

As the writable flag is set to true. We can change the firstName property.
```javascript
person.name = "Ram";
```
Now, let's change the writable flag to false

```javascript

Object.defineProperty(person, "firstName", {
  writable: false,
});

Object.getOwnPropertyDescriptor(person, "firstName");
  /* { 
    value: "Ram", 
    writable: false, 
    enumerable: true, 
    configurable: true
  } */
```
Now, if we try to update the firstName property. Javascript will throw a Type Error:Cannot assign to read only property in strict mode.

```javascript
person.firstName = "Alice"; 
// Cannot assign to read only property in strict mode.

console.log(person.firstName) // Ram
```

##2. Non-Enumrable

As the enumerable flag is set to true for firstName property. If we loop over the  person object the firstName property will be shown up.

```javascript
for (property in person) {
  console.log(property);
}
/* 
  firstName
  lastName
*/
```
Now, let's change the enumerable flag to false.

```javascript

Object.defineProperty(person, "firstName", {
  enumerable: false,
});

Object.getOwnPropertyDescriptor(person, "firstName");
  /* { 
    value: "Ram", 
    writable: true, 
    enumerable: false, 
    configurable: true
  } */
```
Now, if we loop over person object the firstName property will not be shown up.
```javascript
for (property in person) {
  console.log(property);
}
/* 
  lastName
*/
```



##3. Non-Configurable

As the configurable flag is set to true for lastName property. We can delete the lastName property.

```javascript
delete person.lastName;
console.log(person) // { firstName: Ram}
```
Now, let's change the configurable flag to false

```javascript

Object.defineProperty(person, "firstName", {
  configurable: false,
});

Object.getOwnPropertyDescriptor(person, "firstName");
  /* { 
    value: "Ram", 
    writable: true, 
    enumerable: true, 
    configurable: false
  } */
```
Now, if we try to delete the firstName property. Javascript will throw an TypeError: Cannot delete property 'firstName' of #Object
```javascript
delete person.firstName; // Cannot delete property 'firstName' of #Object

console.log(person.firstName) // Ram
```