Constants, Object.freeze, Object.seal and Immutable in JavaScript
Tags: typescript, javascript, webdev, newbie
Published: 2024-06-18 03:00:00

## Introduction

In this article, we're diving into **Immutable** and **Mutable** in JavaScript, while also exploring how functions like **_Object.freeze()_** and **_Object.seal()_** relate to **Immutable**. This is a pretty important topic that can be super helpful in projects with complex codebase.

## So, what's Immutable?

Immutable is like a property of data in JavaScript. It means once the data is created, it can't be changed. This allows for better memory management and catching changes promptly. This is a big deal and totally contrasts with Mutable, which is the default nature when you initialize data in JavaScript.

Implementing Immutable in a project makes development much smoother, reduces issues that crop up, and saves a ton of effort and time for maintenance down the road.

  

## But what happens if you don't use Immutable?

Let me give you an example of how changing data during development can lead to some serious issues.
```ts
let info = {
    name: "name",
    address: "address"
};

function doSomeThing() {
  if (info.name = "Name to compare") { // change value
    // handle something
  }
  info = { name: "Another name" }; //  change value
  // do something else
}

doSomeThing(info);
console.log(info);
```

Here's a simple example to show how data can easily be changed. You might not see a big problem here, but imagine in a large project with lots of complex functions. Changing data like this can hide many risks, leading to unnecessary issues and significantly increasing the time spent tracking issues and maintaining the code.

## Using constants (const)

When a variable is defined as a constant, it means you can't assign a different value to that variable. However, it's important to note that in JavaScript, there are reference types, and even a constant variable's reference value can still be changed.

**For example:**

```ts
const v1 = {a: 1, b: '2', c: [1, 2, 3]}
// v1 = 2 // TypeError: Assignment to constant variable
v1.a = 3 // work
v1.c.push(4) // work
v1['d'] = true // work
delete v1.b // work
console.log(v1)

const v2 = [1, 2, 3]
v2.push(4) // work
console.log(v2)
```

As you can see, even when using constants, the fields within an object can still have their values changed, and new fields can be added or existing ones removed. Generally, data types like **object** (including **array**) remain mutable.

## Using Object.freeze()

This is a built-in function provided by JavaScript to prevent modifications, additions, or deletions of existing fields within an object.

**Let's take a look at an example:**

```ts
const v3 = {a: 1, b: '2', c: [1, 2, 3]}
Object.freeze(v3)
const v3 = Object.freeze({a: 1, b: '2', c: [1, 2, 3]}) // the same with above

// v3 = 2 // TypeError: Assignment to constant variable
// v3.a = 4 // Cannot assign to read only property 'a' of object
v3.c.push(4) // work
// v3['d'] = true // Cannot add property d, object is not extensible
// delete v3.b // Cannot delete property 'b' of #<Object>
console.log(v3)
```

You can see there's a significant improvement in immutability when using **_Object.freeze()_** compared to just using constants. However, for reference types, they can still be altered.

In JavaScript, there's also the **_Object.isFrozen_** function provided to check if a variable is a frozen object.

## Using Object.seal()

With the built-in function Object.seal, it only prevents adding new properties or deleting existing ones, but it still allows changing the value of properties.

```ts
const v5 = {a: 1, b: '2', c: [1, 2, 3]}
Object.seal(v5)
// v4 = 2 // TypeError: Assignment to constant variable
v5.a = 4 // work
v5.c.push(4) // work
// v4['d'] = true // Cannot add property d, object is not extensible
// delete v4.b // Cannot delete property 'b' of #<Object>
console.log(v5)
```

Similarly to **_Object.freeze_**, **_Object.seal_** has the **_Object.isSealed_** function to check if an object is sealed.

## Using the immer library

Let me introduce you to the immer library, which provides comprehensive immutable capabilities, suitable for both Front-end and Back-end development. It's a fantastic library, straightforward to use, and highly recommended by many developers.

Installation: **_npm i immer_**

After that, you can use this library very simply following the instructions below:

```ts
import {Immer, produce} from 'immer'

const immer = new Immer() // default {autoFreeze: true})
const v1 = {a: 1, b: '2', c: [1, 2, 3]}
const v2 = immer.produce(v1, draft => {
  draft.c.push(3, 4) // could do anything with draft value
  return draft
})
// v2.b = '3' // freeze object, Cannot assign to read only property 'b' of object '#<Object>'

const v3 = produce(v2, draft => {
  draft.a = 2
  return draft
})

const immer2 = new Immer({autoFreeze: false})
const v4 = immer2.produce(v1, draft => {
  draft.c.push(3, 4)
  return draft
})
v4.b = '3' // normal object, could be re-assign

console.log('v1', v1)
console.log('v2', v2)
console.log('v3', v3)
console.log('v4', v4)
```

## Conclusion

In this article, I introduced the concept and provided you with examples related to using **_const_**, **_Object.freeze_**, and **_Object.seal_** to support you in implementing immutability in **JavaScript**.

You can combine constants with **_Object.freeze_** or **_Object.seal_** to create immutable objects, as these are features readily supported by **JavaScript**.

However, if you want absolute immutability, then you should use the **immer** library.

**_Happy coding!_**

**_If you found this content helpful, please visit [the original article on my blog](https://howtodevez.blogspot.com/2024/03/constants-objectfreeze-objectseal-and-immutable.html) to support the author and explore more interesting content._**🙏

<a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" target="_blank" rel="noreferrer"><img src="https://img.shields.io/badge/Blogger-FF5722?style=for-the-badge&logo=blogger&logoColor=white" width="36" height="36" alt="Blogspot" /></a><a href="https://dev.to/chauhoangminhnguyen" target="_blank" rel="noreferrer"><img src="https://img.shields.io/badge/dev.to-0A0A0A?style=for-the-badge&logo=dev.to&logoColor=white" width="36" height="36" alt="Dev.to" /></a><a href="https://www.facebook.com/profile.php?id=61557154776384" target="_blank" rel="noreferrer"><img src="https://img.shields.io/badge/Facebook-1877F2?style=for-the-badge&logo=facebook&logoColor=white" width="36" height="36" alt="Facebook" /></a><a href="https://x.com/DavidNguyenSE" target="_blank" rel="noreferrer"><img src="https://img.shields.io/badge/X-000000?style=for-the-badge&logo=x&logoColor=white" width="36" height="36" alt="X" /></a>