Freezing or Sealing? Understanding JavaScript Object Immutability
by Pinta
2 min read
JavaScript, like many dynamic languages, offers flexibility in how you handle objects. But sometimes, you need to ensure
certain objects remain unchanged. That's where Object.freeze()
and Object.seal()
come into play. They're your tools
for creating immutable or partially immutable objects, respectively. Let's dive in!
In programming, immutability means an object's state cannot be changed after it's created. This can help prevent
accidental modifications and make your code more predictable. JavaScript provides a few ways to achieve this, with
freeze()
and seal()
being two prominent methods.
Object.freeze(): Preventing Object Modifications
Object.freeze()
takes your object and encases it in an unbreakable shell. Here's what happens:
- Non-extensible: You cannot add new properties to the object.
- Non-configurable: Existing properties cannot be deleted or have their attributes (configurable, writable, enumerable) changed.
- Non-writable: Values of existing properties cannot be modified.
Example: Frozen Settings
const appConfig = Object.freeze({
theme: "dark",
version: "1.0.0",
maxItems: 100,
});
appConfig.theme = "light"; // Fails silently
appConfig.language = "en"; // Fails silently
delete appConfig.version; // Fails silently
Here, appConfig
is like a locked-down configuration file. Even trying to change its properties directly has no effect.
Object.seal(): Preventing Property Addition and Deletion
Object.seal()
offers a slightly less restrictive form of immutability. Here's how it differs from freeze()
:
- Non-extensible: Just like
freeze()
, you cannot add new properties. - Non-configurable: Existing properties cannot be deleted or have their attributes changed.
- Writable: The values of existing properties can still be modified.
Example: Modifiable Data Record
const userProfile = Object.seal({
name: "Alice",
email: "alice@example.com",
isAdmin: false,
});
userProfile.email = "newalice@example.com"; // Succeeds
userProfile.age = 30; // Fails silently
delete userProfile.isAdmin; // Fails silently
Here, userProfile
is like a sealed record where you can update the information but not add new fields or remove
existing ones.
How to Choose: freeze()
or seal()
?
-
Object.freeze()
: Use when you need absolute immutability for values that should never change under any circumstances. Think of configuration settings, mathematical constants, or any data you want to protect from accidental modifications. -
Object.seal()
: Use when you want a fixed structure for your object but need the flexibility to update the values of existing properties. This is suitable for data records, entities, or objects where the shape is fixed, but the data it holds might evolve over time.
Important Considerations:
-
Shallow vs. Deep Immutability: Both
freeze()
andseal()
provide shallow immutability. If your object has nested objects or arrays, those nested structures are not automatically made immutable. You'd need to recursively applyfreeze()
orseal()
to achieve deep immutability. -
Object.isFrozen() and Object.isSealed(): You can use these functions to check if an object has been frozen or sealed.
Object.isFrozen(appConfig); // true
Object.isSealed(userProfile); // true
In Conclusion
Immutability is a powerful concept in JavaScript, and Object.freeze()
and Object.seal()
are valuable tools to help
you enforce it. Choose the right one based on your specific needs, and remember to handle nested structures for deep
immutability. By embracing immutability, you can make your code more robust, predictable, and easier to reason about.