In this section, we will look at how to make an object immutable in Javascript. We will first look at the freeze() method and later discuss the seal() method and how they help make an object immutable.

Before looking at how to make an object immutable in Javascript, first, let us understand what mutable and immutable objects are.

In mutable objects, we can change the state of the object. Whereas, in immutable objects, we are not allowed to change the state of the object.

"use strict";
let employee = {
    firstName: "Mickey",
    lastName: "Mouse",
    age: 10
};

// Mutable object
employee.firstName = "Donald";

console.log(employee); // {firstName: "Donald", lastName: "Mouse", age: 10}

In the above example, we have created an object employee with properties firstName, lastName and age. If we want to change the value of any of the properties, Javascript allows us to do so.

For example, in our case, we have changed the value of firstName from Mickey to Donald. The object employee is a mutable object where we can change the properties.

However, Javascript allows us to make an object immutable if we want to. Let us look at how we can do so.

Make an object immutable using Object.freeze()

The Object.freeze() method is used to freeze an object. By freeze, we mean you cannot change the existing properties of the object, add new properties or even delete any properties.

Let us make use of the same above example we have discussed above and apply the freeze() method.

"use strict";
let employee = {
    firstName: "Mickey",
    lastName: "Mouse",
    age: 10
};

employee.firstName = "Donald";

console.log(employee); // {firstName: "Donald", lastName: "Mouse", age: 10}

// freeze the employee object
Object.freeze(employee);

employee.firstName = "Mickey"; // Uncaught TypeError

Here, we have frozen the employee object. Hence, if we try to change the firstName property it throws an error: ​​Uncaught TypeError: Cannot assign to read only property 'firstName' of object '#<Object>'.

You are not allowed to add a new property to an immutable object. For example, if try adding a property department to employee it throws an error Uncaught TypeError: Cannot add property department, object is not extensible.

employee.department = "Accounting"; // Uncaught TypeError

Similarly, you cannot delete a property from an immutable object.

delete employee.age; // Uncaught TypeError

The error reads Uncaught TypeError: Cannot delete property 'age' of #<Object>.

Object.seal() method

The Object.seal() method seals the object in a way that you cannot add new properties to it nor delete any existing properties. However, you are allowed to make changes to the existing properties.

"use strict";
let employee = {
    firstName: "Mickey",
    lastName: "Mouse",
    age: 10
};

// Seal the employee object
Object.seal(employee);

employee.firstName = "Donald";

console.log(employee); // {firstName: "Donald", lastName: "Mouse", age: 10}

//add a new property
employee.department = "Accounting"; // Uncaught TypeError

//delete an existing property
delete employee.age; // Uncaught TypeError

Object.freeze() vs Object.seal()

In seal() method we are allowed to change the values of existing properties. But, when we use the freeze() method, we cannot change the existing properties. For example,

"use strict";
let employee = {
    firstName: "Mickey",
    lastName: "Mouse",
    age: 10
};

// Seal the employee object
Object.seal(employee);

employee.firstName = "Donald";

console.log(employee); // {firstName: "Donald", lastName: "Mouse", age: 10}

However, if we tried the same using the freeze() method, we will encounter an TypeError.

"use strict";
let employee = {
    firstName: "Mickey",
    lastName: "Mouse",
    age: 10
};

// Freeze the employee object
Object.freeze(employee);

employee.firstName = "Donald";  // Uncaught TypeError

The property firstName is a read-only property in this case and we cannot change its value.

Setting the writable attribute of a property

There are might be a case where you want to only make certain properties in an object immutable. To do this we can make use of the writable attribute.

For example, in our employee object we don’t want to change the firstName but we want to be able to change the lastName and age of the object.

"use strict";
let employee = {
    firstName: "Mickey",
    lastName: "Mouse",
    age: 10
};

Object.defineProperty(employee, 'firstName', {
    writable: false
});

// allowed
employee.age = 20;

console.log(employee); // {firstName: 'Mickey', lastName: 'Mouse', age: 20}

// Not allowed
employee.firstName = "Donald"; // Uncaught TypeError

We make use of the defineProperty method of the Object and set the firstName property’s writable attribute as false. This way we can make the a specific property immutable.