Object Protection in JavaScript
In JavaScript, objects are dynamic by default — meaning their properties can be added, changed, or deleted at any time. However, in some cases (like configurations, constants, or sensitive data), you might want to protect objects from modification.
JavaScript provides several built-in methods for object protection, allowing you to control how mutable (changeable) an object is.
Levels of Object Protection
Protection Level | Method | Can Add Properties? | Can Modify Existing? | Can Delete Properties? |
---|---|---|---|---|
Non-extensible | Object.preventExtensions() | No | Yes | Yes |
Sealed | Object.seal() | No | Yes | No |
Frozen | Object.freeze() | No | No | No |
Object.preventExtensions()
Prevents adding new properties to an object, but existing ones can still be modified or deleted.
Example:
const user = { name: "John" };
Object.preventExtensions(user);
user.age = 30; // Not allowed
user.name = "Jane"; // Allowed
delete user.name; // Allowed
console.log(user); // {}
console.log(Object.isExtensible(user)); // false
Object.seal()
Prevents adding or deleting properties, but allows modifying existing values.
All properties become non-configurable.
Example:
const person = { name: "John" };
Object.seal(person);
person.age = 25; // Can't add
person.name = "Jane"; // Can modify
delete person.name; // Can't delete
console.log(person); // { name: "Jane" }
console.log(Object.isSealed(person)); // true
Object.freeze()
Highest level of protection.
Prevents:
- Adding properties
- Deleting properties
- Modifying property values
Example:
const config = { appName: "MyApp" };
Object.freeze(config);
config.appName = "NewApp"; // No effect
config.version = 1.0; // No effect
delete config.appName; // No effect
console.log(config); // { appName: "MyApp" }
console.log(Object.isFrozen(config)); // true
Deep Freeze (for Nested Objects)
Object.freeze()
only freezes the top-level object.
To protect nested objects, you must recursively freeze them.
Example:
function deepFreeze(obj) {
Object.freeze(obj);
for (let key in obj) {
if (typeof obj[key] === "object" && obj[key] !== null) {
deepFreeze(obj[key]);
}
}
return obj;
}
const settings = {
ui: { theme: "dark" },
version: 1
};
deepFreeze(settings);
settings.ui.theme = "light"; // No effect
console.log(settings.ui.theme); // "dark"
Checking Protection Status
Check Type | Method | Returns |
---|---|---|
Is Extensible? | Object.isExtensible(obj) | true / false |
Is Sealed? | Object.isSealed(obj) | true / false |
Is Frozen? | Object.isFrozen(obj) | true / false |
Practical Example (Comparison)
const obj = { a: 1 };
// preventExtensions
Object.preventExtensions(obj);
obj.b = 2; //
// seal
Object.seal(obj);
delete obj.a; //
obj.a = 10; //
// freeze
Object.freeze(obj);
obj.a = 5; //
Real-World Use Cases
Scenario | Protection Method | Reason |
---|---|---|
Configuration constants | Object.freeze() | Prevent accidental changes |
API Response objects | Object.seal() | Prevent structure modification |
Framework settings | Object.preventExtensions() | Limit expansion of object |
Immutable State (React, Redux) | deepFreeze() | Ensure predictable, pure updates |