Object Property Descriptor

Do you know there are certain ways you could protect your objects from external influences like reading, writing, or even deletion in JavaScript?. In this article, the object property descriptor which are responsible for the various actions that can be carried out on Javascript object properties are discussed.

Property Descriptors

In Javascript objects, each key value pair has some attributes that define the state of the key-value pair. There are six of these attributes:

  • Getter: Defines a getter function that's used to get a value from the object.

  • Setter: Defines a setter function that's used to set the value of an object key.

  • Value: Is the value associated with a key.

  • Enumerable: An attribute that describes whether or not the key-value pair should be accessible in a for -in loop.

  • Configurable: An attribute that tells whether or not a key-value pair can be deleted.

  • Writable: An attribute that tells whether or not a value associated with a key can be modified.

These attributes are not readily exposed to the developer. However, it can be shown by calling the getOwnPropertyDescriptor method on the Object instance.

To do this, pass the object and its key as arguments to the getOwnPropertyDescriptor thus:

const obj={
  first:"John",
  last:"Doe"
}
console.log(Object.getOwnPropertyDescriptor (obj, "first"))
//{value:"John", writable true, enumerable:true, configurable:true}

Note that all the attributes are true by default.

Setting Property Descriptors

There are different ways to create an object in JavaScript, one of such ways is by calling the defineProperty method on the Object instance and passing the required object, the new key you want to create, and its attributes as arguments thus:

Object.defineProperty(obj, "age", {value:60})
console.log(obj)
//{first:"John",last:"Doe",age:60}

Note that the third argument is an object with a compulsory key named value which holds the required value you want to store in the object.

Every key-value pair created with this method will have all its attributes default to false.

Object.defineProperty(obj, "age", {value:60})
console.log(Object.getOwnPropertyDescriptor(obj,"age"))
//{ value: 60, writable: false, enumerable: false, configurable: false

Therefore, this key-value pair cannot be:

  • Deleted,

  • Edited

  • Evaluated in a for-in loop or Object.keys method.

Object.defineProperty(obj, "age", {value:60})
delete obj.age
for (key in obj){
  console.log(key)
// "first", "last"
}
obj.age=25:
console.log(obj)
//{first:"John",last:"Doe",age:60}

You can however decide the state of these attributes yourself and this iis where the beauty lies:

Object.defineProperty(obj, "age", {
value:60, 
writable: true, 
enumerable: true, 
configurable:true 
})

Now we can carry out all the previous operations on the key-value pair.

Protecting The Object From External Interference

Sometimes, we want to put certain restrictions on objects. Luckily, JavaScript provides three different methods to provide restrictions on object:

Object.preventExtensions

This method prevents any other key-value pair to be added to the object. In essence, it doesn't allow the create operation.

Object.preventExtensions(obj)
obj.speech="Hello"
console.log(obj)
//{first:"John",last:"Doe",age:60}

To check if an object is extensible, use the Object.isExtensible method:

console.log(Object.isExtensible(obj))// false

Object.seal

This is essentially a guard against the create and delete operations.

That is, neither can the object accept a new key-value pair nor remove a key-value pair.

Object.seal(obj)
obj.speech="Hello"
delete obj.age
console.log(obj)
console.log(Object.isSealed(obj)) //true

Object.freeze

This is the highest level of protection. It essentially freezes the object. The only CRUD operation that can be done on it is only the READ operation.

In other words, Object.freeze makes the object readonly.

Object.freeze(obj)
obj.speech="Hello"
delete obj.age
obj.first="Johnny"
console.log(obj) //{first:"John",last:"Doe",age:60}
console.log(Object.isFrozen(obj)) //true

Conclusion

In this article, we learnt about some of the not-so-obvious features of javascript objects. This knowledge should hopefully help us in writing more robust JavaScript codes.