DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 970,177 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Dragoljub Bogićević
Dragoljub Bogićević

Posted on

JavaScript - How to make objects immutable?

In this post, we will learn a couple of ways of creating immutable objects in JavaScript, as well what are the pros and cons of each approach. Object immutability will reduce side-effects and unpredictable behavior.
We will cover:

  • const
  • preventExtentions
  • seal
  • freeze

Note: this also applies for TypeScript

1. const

The first to come to mind is, of course, const, const prevents re-assign the object but the object's contents (e.g., its properties) can be altered.

Let's see the example:

const person = {
    firstName: 'pera',
    lastName: 'trta',
    address: {
        street: 'street'
    }
}; 

// person = false;                    // re-assign is not allowed
person.firstName = 'pera pera';       // update is allowed
person.middleName = 'pt';             // add is allowed
person.address.street = 'street 123'; // update is allowed
delete person.lastName;               // delete is allowed

2. preventExtentions

As we saw, const has a drawback regarding object immutability. Another alternative is Object.preventExtensions() a method which prevents adding new properties to the object (updating and deleting existing properties is still allowed).

const person = {
    firstName: 'pera',
    lastName: 'trta',
    address: {
        street: 'street'
    }
};

Object.preventExtensions(person);
// true
console.log(Object.isExtensible(person));

// person = false;                    // re-assign is not allowed
person.firstName = 'pera pera';       // update is allowed
person.middleName = 'pt';             // add is not allowed
delete person.lastName;               // delete is allowed
person.address.street = 'street 123'; // update is allowed *
person.address.newProperty = 7;       // update is allowed *

* Please, keep reading, explanation is at the end of the post.

3. seal

Another Object's method is seal. This one will prevent adding (sealing an object prevents new properties from being added) new and deleting existing properties to and from the object (updating existing properties is still allowed).

const person = {
    firstName: 'pera',
    lastName: 'trta',
    address: {
        street: 'street'
    }
};

Object.seal(person);

// sealed objects are by definition non-extensible
console.log(Object.isExtensible());
// true
console.log(Object.isSealed());

// person = false;                    // re-assign is not allowed
person.firstName = 'pera pera';       // update is allowed
person.middleName = 'pt';             // add is not allowed
delete person.lastName;               // delete is not allowed
person.address.street = 'street 123'; // update is allowed *
person.address.newProperty = 7;       // but here add is allowed *

* Please, keep reading, explanation is at the end of the post.

4. freeze

Another Object's method is freeze - freezes an object. A frozen object can no longer be changed; freezing an object prevents new properties from being added, updated or removed.

const person = {
    firstName: 'pera',
    lastName: 'trta',
    address: {
        street: 'street'
    }
};

Object.freeze(person);

// freezed objects are by definition non-extensible
console.log(Object.isExtensible());
// true
console.log(Object.isFrozen());

// person = false;                    // re-assign is not allowed
person.firstName = 'pera pera';       // update is not allowed
person.middleName = 'pt';             // add is not allowed
delete person.lastName;               // delete is not allowed
person.address.street = 'street 123'; // but here update is allowed *
person.address.newProperty = 7;       // here add is allowed as well *

* So, what is going on lines with the asterisk sign?

The result of calling Object.preventExtensions(object), Object.seal(object), Object.freeze(object) only applies to the immediate properties of object itself which means if the value of those properties are objects themselves (in our case property address is an object), those objects are not affected by the methods. The solution for this issue will be in another post.

Thank you for reading!

Oldest comments (0)

Have you saved a post on DEV?

Head to your Reading List to read and manage the posts you've saved.