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 we found the answer:
What is “shallow freeze”?
The result of calling
Object.freeze(object)
only applies to the immediate properties ofobject
itself and will prevent future property addition, removal or value re-assignment operations only onobject
. 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:
Now the only task left is to freeze each branch of our tree:
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
Thanks for reading! Feel free to hit the recommend if you found this article helpful.
Top comments (0)