Object.freeze(), object.seal() and object.assign() in JavaScript
Object Static Methods
JavaScript provides several important static methods on Object for controlling object mutability and copying properties.
Object.freeze()
Makes an object completely immutable β no adding, removing, or modifying properties:
const config = Object.freeze({
apiUrl: "https://api.example.com",
timeout: 5000
});
config.apiUrl = "changed"; // β Silently fails (throws in strict mode)
config.newProp = "value"; // β Silently fails
delete config.timeout; // β Silently fails
console.log(config.apiUrl); // "https://api.example.com" (unchanged)Shallow Freeze
Object.freeze() is shallow β nested objects are not frozen:
const user = Object.freeze({
name: "Alice",
address: { city: "Kyiv" } // Nested object is NOT frozen
});
user.name = "Bob"; // β Fails
user.address.city = "Lviv"; // β
Works! (nested object is mutable)Deep Freeze
function deepFreeze(obj) {
Object.freeze(obj);
Object.values(obj).forEach(value => {
if (typeof value === "object" && value !== null) {
deepFreeze(value);
}
});
return obj;
}Object.seal()
Prevents adding or removing properties, but allows modifying existing values:
const user = Object.seal({
name: "Alice",
age: 25
});
user.name = "Bob"; // β
Can modify existing properties
user.email = "a@b.com"; // β Cannot add new properties
delete user.age; // β Cannot delete properties
console.log(user); // { name: "Bob", age: 25 }Comparison: freeze vs seal vs regular
| Operation | Regular Object | Object.seal() | Object.freeze() |
|---|---|---|---|
| Read properties | β | β | β |
| Modify values | β | β | β |
| Add properties | β | β | β |
| Delete properties | β | β | β |
| Reconfigure descriptors | β | β | β |
Checking Object State
Object.isFrozen(frozenObj); // true
Object.isSealed(sealedObj); // true
Object.isExtensible(regularObj); // true (can add properties)Object.assign()
Copies enumerable own properties from one or more source objects to a target object:
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
const result = Object.assign(target, source1, source2);
console.log(result); // { a: 1, b: 2, c: 3 }
console.log(target); // { a: 1, b: 2, c: 3 } β target IS modified!
console.log(result === target); // trueCommon Patterns
// Merge without mutating (create new object)
const merged = Object.assign({}, defaults, userSettings);
// Same with spread (preferred)
const merged = { ...defaults, ...userSettings };
// Clone an object (shallow)
const clone = Object.assign({}, original);
const clone = { ...original }; // Same thingShallow Copy Warning
const original = {
name: "Alice",
address: { city: "Kyiv" }
};
const copy = Object.assign({}, original);
copy.address.city = "Lviv";
console.log(original.address.city); // "Lviv" β nested object shared!Object.preventExtensions()
Prevents adding new properties, but allows modification and deletion:
const obj = Object.preventExtensions({ a: 1, b: 2 });
obj.a = 10; // β
Can modify
delete obj.b; // β
Can delete
obj.c = 3; // β Cannot addImportant:
Use Object.freeze() for constants and configuration objects. Use Object.seal() when you want to allow modifications but prevent structural changes. Prefer the spread operator ({ ...obj }) over Object.assign() for creating copies. Remember all these operations are shallow.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.