How to deep-freeze an object in JavaScript ?
In this article, we will see what is the problem with objects in JavaScript and why we need to “deep-freeze” an object in JavaScript. We will also learn how to “deep-freeze” an object in JavaScript.
Problem with Object in JavaScript: We all know that JavaScript objects are mutable. How can we make them immutable? Define them as const but if we declare a JavaScript object as a const, it only prevents the object from getting reassigned as a whole. We can still reassign the properties and change their value.
Example 1:
HTML
< script > const obj1 = { key1: "val1", key2: "val2", key3: "val3" }; console.log("Before Change"); console.log(obj1); obj1.key1 = "val"; console.log("After Change"); console.log(obj1); </ script > |
Output:
"Before Change" { key1: "val1", key2: "val2", key3: "val3" } "After Change" { key1: "val", key2: "val2", key3: "val3" }
How to fix the above problem?
We can use an Object.freeze() method provided by JavaScript to prevent the addition of new properties with updating and deleting of existing properties.
Example 2:
Javascript
const obj1={key1: "val1" , key2: "val2" , key3: "val3" } console.log( "Before Change" ) console.log(obj1); Object.freeze(obj1); obj1.key1= "val" ; console.log( "After Change" ) console.log(obj1); |
Output:
"Before Change" { key1: "val1", key2: "val2", key3: "val3" } "After Change" { key1: "val1", key2: "val2", key3: "val3" }
This is not the best approach because it only creates a shallow object freeze and if the object has some nested object/array as the property the nested object/array can still be modified.
Example 3:
HTML
< script > const obj1 = { key1: "val1", key2: "val2", key3: ["val3", "val4", "val5"] }; console.log("Before Change"); console.log(obj1); Object.freeze(obj1); obj1.key3[0] = "val"; obj1.key3[1] = "val"; obj1.key3[2] = "val"; console.log("After Change"); console.log(obj1); </ script > |
Output: This is the situation when we need to create a deep freeze for an object.
"Before Change" { key1: "val1", key2: "val2", key3: ["val3", "val4", "val5"] } "After Change" { key1: "val1", key2: "val2", key3: ["val", "val", "val"] }
How to implement it?
We will use recursion for implementing the deep freeze of the object. The idea is to check if each property is an object or not. If the property is an object we will check whether it is frozen or not. If not frozen, call the freeze function on that property recursively. In this way, we will create a deep freeze of the object.
Example 4:
HTML
< script > const obj1 = { key1: "val1", key2: "val2", key3: ["val3", "val4", "val5"] }; const deepFreeze = (obj1) => { Object.keys(obj1).forEach((property) => { if ( typeof obj1[property] === "object" && !Object.isFrozen(obj1[property]) ) deepFreeze(obj1[property]); }); return Object.freeze(obj1); }; deepFreeze(obj1); console.log("Before Change"); console.log(obj1); obj1.key3[0] = "val"; obj1.key3[1] = "val"; obj1.key3[2] = "val"; console.log("After Change"); console.log(obj1); </ script > |
Output:
"Before Change" { key1: "val1", key2: "val2", key3: ["val3", "val4", "val5"] } "After Change" { key1: "val1", key2: "val2", key3: ["val3", "val4", "val5"] }
Please Login to comment...