The problem with Object.freeze
Published: 2020-04-22 16:27:53

In several situations, we need to ensure that some Object values and methods won’t change anymore; some examples are:

-   A list with access keys to external web services
-   An object with a unique ID that represents the user or current session
-   Information about the user device like the operating system, browser version and name and more.

To solve problems like this my first approach was relying upon in `Object.freeze` function, let’s take an example:

```
const myCustomObj = {  
  thisObjectWillChange: "nope ",  
};  
  
Object.freeze(myCustomObj);  
  
myCustomObj.thisObjectWillChange = "trying change this 🤔";  
  
console.log(myCustomObj.thisObjectWillChange); // will return: nope

```

So far so good, it worked as we expected, but something works weird when we increase the number of branches of our object tree-like in this example:

```
const accessKeys = {  
  aws: {  
   accessKeyId: 'abc123',  
   secretAccessKey: 'secretValue'  
 },  
 google: 'gogole123'  
}
Object.freeze(accessKeys);
accessKeys.aws.accessKeyId = 'trying to change this value 😰';

console.log(accessKeys.aws.accessKeyId); // will return 'trying to change this value 😰'

```

So, what’s happened wrong? Why the `Object.freeze` won’t prevent this alteration? When we check the [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) we found the answer:

> **What is “shallow freeze”?**
> 
> The result of calling `Object.freeze(object)` only applies to the immediate properties of `object` itself and will prevent future property addition, removal or value re-assignment operations only on `object`. If the value of those properties are objects themselves, those objects are not frozen and may be the target of property addition, removal or value re-assignment operations.

The problem isn’t only editing the value, but is also possible add new attributes and delete the current attributes in other branches except for the root, in this branches is like we don’t have anything froze, terrible right?

To solve this we need to apply the `Object.freeze` again in these branches, something like this:

```
const accessKeys = {  
  aws: {  
   accessKeyId: 'abc123',  
   secretAccessKey: 'secretValue'  
 },  
 google: 'gogole123'  
}
Object.freeze(accessKeys);  
Object.freeze(accessKeys.aws);
accessKeys.aws.accessKeyId = 'trying to change this value';
console.log(accessKey.aws.accessKeyId); ***//will return 'abc123'* 😃**
```

But you know, if you have many subattributes could be hard to freeze all inner branches, to help us to make it easier we have the method `Object.getPropertyNames` available, with this method we get the keys of each branch, and we could navigate inside our object using recursion:

{% gist https://gist.github.com/rxluz/651909d08197c2ea7762f1caee43daed %}

Now the only task left is to freeze each branch of our tree:

{% gist https://gist.github.com/rxluz/3642f41f543462de2c34d92916a3d8d0 %}

If you to want to know more about **Javascript** I recommend these books:

-   **You Don’t Know JS Serie by Kyle Simpson (My favourite)**
-   **Eloquent JS by Marijn Haverbeke**
-   **Head First Javascript by Michael Morrison**
-   **Secrets of the JavaScript Ninja by Bear Bibeault and John Resig**

[Ricardo Luz (@\_rxluz) | Twitter](https://twitter.com/_rxluz)

***Thanks for reading! Feel free to hit the recommend if you found this article helpful.***