Immutability in JavaScript: 3 Methods
Published: October 12, 2021
Immutability means something cannot be changed. You might want this to make sure you're preserving a value.
For example, if you're having multiple functions input the same value, but the value can potentially change between the function's operations, you'll want to ensure the original value isn't accidentally getting overwritten somewhere in the process.
1. CONST
Most of the time, this is the start and end of immutability. It's lesson one for anyone learning ES6 JavaScript and onward.
Using const
lets you assign immutable primitive values. Declare a string, number, or boolean variable with const
and it will never change.
This is not the case with object literals. Using const
for an object will still allow you to add or change keys and values within the object.
Use const
with primitive values for immutability. You'll need something else for objects. Arrow functions declared with const
are also immutable. Declaring an arrow function with let
allows it to be entirely overwritten.
2. OBJECT.FREEZE()
Object.freeze()
does what it sounds like—freezes an object literal and makes it truly immutable. Here's an example:
const obj = { key: 'value' }; Object.freeze(obj); obj.key = 'newValue'; // This will not change the value console.log(obj.key); // 'value'
Once an object is frozen, it will not change. When you absolutely need an object literal to remain exactly how it is, use Object.freeze()
.
This also works on arrays in JavaScript.
You might be thinking "everything is an object in JavaScript, including primitives. So does that mean it works on all? Sadly, no. For example, if you try to freeze a string set with normal var
declaration, it won't affect mutability at all.
3. OBJECT.DEFINEPROPERTY()
Using Object.defineProperty()
, you can determine mutability on a specific property within an object. While the rest of the values within the object are as mutable as ever, you can "lock" an object in.
const rabbits = { two: 2 }; Object.defineProperty(rabbits, 'two', { writable: false }); rabbits.two = 4; // This will not change the value
The great thing about this kind of immutability is it's not permanent. Yes, okay, maybe that doesn't truly make it immutable. Nevertheless, it warrants being mentioned on this list.
Making it writable again is the exact same process as before:
Object.defineProperty(rabbits, 'two', { writable: true });
After changing the pair's writable
status to true
, it could again be manipulated as usual.
Bonus: PRIVATE KEYWORDS
Okay, this isn't a proper feature of JavaScript. It's been proposed but is not widely supported with JS engines. But it's still interesting, so I'll mention it. As a treat.
Using #
at the beginning of a named variable to make it the equivalent to the private
keyword in Java classes.
E.g. #variableName
for a value or function declaration would only make that function accessible inside the class it's declared.
This doesn't mean the field is legitimately immutable. It's only immutable in the sense that you won't be able to change or even access it outside of the class, even though you normally would be able to normally.
This isn't truly immutable, but it's still a neat trick to make a field a bit less mutable. If you need to change or access a private field, that's when you reach back into OOP-land and rediscover getters and setters.
— Deeter Cesler