Freeze vs. Seal: Javascript Object Immutability

Immutability is an essential feature in programming. When passing around or exposing your data, it is at risk of being mutated in ways you aren’t expecting. Two ways to help prevent this with JavaScript are to “freeze” or “seal” your objects.
Object.freeze()
and Object.seal()
are similar methods. They take a POJO, (Plain old JavaScript Object), and restrict the object’s functionality to help keep information safe from unexpected changes. But they work in slightly different ways.
Object.freeze()
can be thought of as the more thorough of the two. It prevents any changes to the Objects’ properties. Once frozen, no properties can be added, removed, or altered.
Here we can see the Object has not changed since it’s instantiation. It is however important to note that when attempting to add or change the properties of an object in strict mode, a TypeError will be thrown. Otherwise it will fail silently. I’m running this code in the browser, so I’m returned the value that I’m attempting to set my variables to. Just remember that attempting to change a frozen Object in your codebase may cause errors to be thrown.
There are a few more things to keep in mind here. One is that even though the Object are frozen, you can still point your variable to a different object. This is an excellent example of why const
is important for immutability.
Here we can see that since alsoMyObj was declared with const, it remains pointing to the original object. We can also see that freeze() is working on the object itself, not the variable that points to it.
Another important thing to remember with freeze, is that it doesn’t work on the properties of nested objects.
Here you can see that functions, like variables or primitive data, can not be changed once frozen. You can’t even change the variable two
and point it to a new object. But you can change the properties inside of the object that two
is pointing to. This is because the two
property is pointing to an Object that is completely separate in memory, and thus it would have to be frozen itself to prevent changes from taking place. If you wanted to, you could do this with chaining inside the freeze method: Object.freeze(myObj.two)
.
Object.seal()
is not quite as strict as freeze. With seal, you can still mutate the data inside the Object. You just can’t add any new properties, or delete the existing properties.
Here we can see the values for our properties can be changed, but we can’t add or remove any properties.
You can check if an Object is frozen or sealed with the Object.isFrozen()
and Object.isSealed()
methods.
Keep in mind that once an Object is frozen, it can’t be unfrozen. There is no unfreeze or unseal method available. To alter the data once frozen or sealed, you would have to copy the data to a new Object, and start mutating the Object copy.
One last important thing to remember, is that Arrays and Functions are Objects too in JavaScript. This means freeze and seal can both be applied to Arrays and Functions. Once frozen or sealed, you can’t push, pop, shift, or unshift from an Array. And while you can’t change the variable that points to a function inside a frozen Object, the function that it points to can still be altered if not frozen itself.
When needed, freeze and seal can be very useful to keep your data from being accidentally altered. But it’s important to know how they work, and where their functionality starts and ends.