Object.freeze, Object.seal & Immutability0%
Object.freeze, Object.seal & Immutability
Beginner12 min read•Updated: Jul 11, 2026
Object.freeze, Object.seal & Immutability in Modern JavaScript
In state management systems (Redux, Zustand) and security configurations, accidental object mutation causes hard-to-track bugs. Modern JavaScript provides varying levels of object locking: Object.preventExtensions(), Object.seal(), and Object.freeze().
1. The Immutability Spectrum
Output
┌────────────────────────────────────────────────────────┐
│ Level 1: Object.preventExtensions(obj) │
│ • CANNOT add new properties │
│ • CAN modify existing properties │
│ • CAN delete existing properties │
├────────────────────────────────────────────────────────┤
│ Level 2: Object.seal(obj) │
│ • CANNOT add new properties │
│ • CANNOT delete existing properties │
│ • CAN modify existing property values │
├────────────────────────────────────────────────────────┤
│ Level 3: Object.freeze(obj) │
│ • CANNOT add new properties │
│ • CANNOT delete existing properties │
│ • CANNOT modify existing property values (Read-Only) │
└────────────────────────────────────────────────────────┘
2. Property Descriptors Explained
Under the hood, these methods configure internal Property Descriptors:
JavaScript
const user = { name: 'Sarah' };
// Inspect property descriptor
console.log(Object.getOwnPropertyDescriptor(user, 'name'));
// { value: 'Sarah', writable: true, enumerable: true, configurable: true }
writable: Iffalse, value cannot be reassigned.configurable: Iffalse, property cannot be deleted and descriptors cannot be modified.enumerable: Iffalse, hidden fromfor...inandObject.keys().
JavaScript
// Object.freeze() sets:
// 1. Object extensible = false
// 2. All own properties: writable = false, configurable = false
3. Strict Mode Enforcement
In non-strict mode, attempting to mutate a frozen object fails silently. In strict mode ('use strict'), it throws a TypeError:
JavaScript
'use strict';
const appConfig = Object.freeze({
apiEndpoint: 'https://api.example.com',
timeout: 5000
});
// appConfig.timeout = 10000;
// TypeError: Cannot assign to read only property 'timeout' of object '#<Object>'
4. The Critical Gotcha: Object.freeze is SHALLOW!
Object.freeze() only freezes top-level properties. Nested objects remain mutable references!
JavaScript
const enterpriseSettings = Object.freeze({
appName: 'MasterPortal',
database: {
host: 'localhost', // NESTED OBJECT!
port: 5432
}
});
// DANGER: Nested mutation succeeds!
enterpriseSettings.database.port = 3306;
console.log(enterpriseSettings.database.port); // 3306!
The Solution: Recursive Deep Freeze Utility
JavaScript
function deepFreeze(obj) {
// Retrieve all own property names
const propNames = Object.getOwnPropertyNames(obj);
// Freeze properties before freezing self
for (const name of propNames) {
const value = obj[name];
if (value && typeof value === 'object') {
deepFreeze(value); // Recursive call
}
}
return Object.freeze(obj);
}
const safeSettings = deepFreeze({
database: { port: 5432 }
});
// safeSettings.database.port = 3306; // TypeError: Cannot assign to read only property!
Interactive Quiz
Practice Quiz
Question 1
What is the primary difference between Object.seal() and Object.freeze()?
Question 2
What happens when code attempts to mutate a frozen object in strict mode ('use strict')?
Question 3
Does calling Object.freeze(obj) prevent modifications to nested objects (e.g. obj.nested.key = val)?
Question 4
Which method checks whether an object has been sealed?
Question 5
What property descriptor controls whether a property can be deleted with the delete operator?
Next Lesson
Symbols & Well-Known Symbols
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| WeakMap & WeakSet for Memory Management | Symbols & Well-Known Symbols |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.