When Objects Stop Changing: Rethinking Freezing and Sealing in JavaScript
Object.seal and Object.freeze restrict how objects can be modified, with sealing locking the structure while allowing value changes, and freezing making both structure and values immutable, though only at the top level.
At first, JavaScript objects feel completely open.
You can change them.
Extend them.
Remove parts of them.
const user = { name: "Rishi" }
user.name = "Indana"
user.age = 24
delete user.nameEverything is allowed.
And that flexibility is part of what makes JavaScript feel easy.
But over time, that same flexibility becomes a source of risk.
Because if everything can changeâ
then anything might.
The Need for Constraints
As applications grow, certain objects begin to carry more weight.
Configuration.
Shared state.
Core structures.
These are not meant to evolve freely.
They are meant to remain stable.
And thatâs where JavaScript introduces a quiet idea:
Not all objects should be equally mutable
Sealing: Locking the Shape
When you seal an object, you donât stop it from changing entirely.
You stop it from growing or shrinking.
Object.seal(user)Now:
- existing properties can still change
- new properties cannot be added
- existing properties cannot be removed
The structure becomes fixed.
But the values remain flexible.
Itâs a subtle boundary.
The object can evolveâ
but only within its original shape.
Freezing: Locking Everything
Freezing goes further.
Object.freeze(user)Now, the object becomes immutable:
- values cannot change
- properties cannot be added
- properties cannot be removed
What was once flexible becomes fixed.
Not just in structureâ
but in content.
A Spectrum of Control
Seen together, these methods form a spectrum:
- normal objects â fully flexible
- sealed objects â fixed shape, flexible values
- frozen objects â completely fixed
They allow you to choose how much change is allowed.
Not globallyâ
but intentionally.
The Unexpected Detail
There is, however, a subtle twist.
Freezing is shallow.
const user = {
name: "Rishi",
address: {
city: "Jakarta"
}
}
Object.freeze(user)You cannot change user.name.
But you can still change:
user.address.city = "Bandung"Because the nested object was never frozen.
What looks immutable on the surfaceâ
may still be mutable underneath.
Not Just About Safety
Freezing and sealing are often described as ways to âprotectâ objects.
But they are also about clarity.
They make your intent explicit.
They tell anyone reading your code:
âThis should not change.â
And that matters.
Because constraints are a form of communication.
A Different Way to Think About Objects
Instead of seeing objects as containers of data,
you begin to see them as entities with rules.
Some are flexible.
Some are partially restricted.
Some are fixed.
And those differences are not accidental.
They are designed.
Where This Becomes Useful
In practice, these tools appear in places where stability matters:
- configuration objects that should not drift
- shared state that must remain predictable
- APIs that should not be redefined
They donât add functionality.
They remove uncertainty.
A Final Thought
JavaScript begins as a language of freedom.
Everything can change.
Everything is open.
But as systems grow, that freedom needs balance.
Because not everything should be mutable.
And once you start deciding what should stay fixedâ
your code stops being just flexibleâŚ
and starts being intentional.