How to use Object.freeze() in Javascript

Arika O - Oct 16 '20 - - Dev Community

In Javascript, objects and arrays are mutable, primitive values are not. This means we can change an object (or array) anytime we want. But what if for some reason we want to stop this from happening and make the object immutable?

One way we we can achieve this is by using the freeze() method.

A frozen object can no longer be changed; freezing an object prevents new properties from being added to it, existing properties from being removed, prevents changing the enumerability, configurability, or writability of existing properties, and prevents the values of existing properties from being changed. In addition, freezing an object also prevents its prototype from being changed. freeze() returns the same object that was passed in.

Some code illustrating the usage of this method would look something like this:

const objectExample = {
  prop1: 42,
  prop2: "Jack"
};

// by default, we can modify the object's properties as we want
objectExample.prop1 = 100;
console.log(objectExample.prop1) // prints 100

// now let's freeze the object
Object.freeze(objectExample);

objectExample.prop2 = "Alice" // will throw an error in strict mode but fail silently in non-strict mode

console.log(objectExample.prop2); // prints "Jack", since we couldn't change the value of the prop
Enter fullscreen mode Exit fullscreen mode

Something to keep in mind is that if the frozen object has properties with objects as values, those objects can be changed unless we also froze them. This means we only achieved a shallow freeze. To make objects immutable by freezing all their properties, including the ones that store other objects as values, we must do a deep freeze - that is freezing the children objects before freezing the parent object, using recursion.

The function below is just and example. You can name yours as you wish. Be careful when freezing objects as values of properties so you don't freeze something that shouldn't become immutable.

const theObject = {
  x: 1,
  z: 2,
  y: {
    a: "Hello",
    b: "World"
  }
}

const deepFreeze = (obj) => {

  const propNames = Object.getOwnPropertyNames(obj)

  for (const name of propNames) {
    const value = obj[name];

    if (value && typeof value === "object") { 
      deepFreeze(value);
    }
  }

  return Object.freeze(obj);
}

deepFreeze(theObject);
theObject.y.a = 456; // the value can't be changed
console.log(theObject.y.a ); // Hello
Enter fullscreen mode Exit fullscreen mode

Image source: Caspar Camille Rubin/ @casparrubin on Unsplash

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player