Quiz

What is `Object.freeze()` for?

Topics
JavaScript

TL;DR

Object.freeze() makes an object non-extensible and changes its own properties so they cannot be removed or reconfigured; data properties also become non-writable. This is a shallow operation: nested objects and internal state such as a Map's entries can still change. Invalid writes throw in strict mode and otherwise usually fail silently.

const obj = { name: 'John' };
Object.freeze(obj);
obj.name = 'Doe'; // This will not change the name property
console.log(obj); // { name: 'John' }

What is Object.freeze() for?

Object.freeze() prevents additions, removals, reconfiguration, and writes to an object's own data properties. It is useful as a shallow guard against accidental mutation, but it does not make an arbitrary object graph deeply immutable.

How to use Object.freeze()

To use Object.freeze(), pass the object you want to freeze as an argument to the method. Here is a basic example:

const obj = {
name: 'John',
age: 30,
};
Object.freeze(obj);
obj.name = 'Doe'; // This will not change the name property
obj.gender = 'male'; // This will not add a new property
delete obj.age; // This will not delete the age property
console.log(obj); // Output: { name: "John", age: 30 }

Characteristics of a frozen object

  1. Shallow integrity: The frozen object's own data properties cannot be changed, added, or removed. Referenced objects are unaffected.
  2. Non-extensible: A frozen object is also non-extensible, meaning you cannot add new properties to it.
  3. Non-configurable: The properties of a frozen object become non-configurable, meaning you cannot change property descriptors.

Use cases for Object.freeze()

  1. Constants: When you want to create a constant object that should not be modified.
  2. Data integrity: Ensuring that an object remains unchanged throughout the lifecycle of an application.
  3. Defensive programming: Catching or preventing accidental writes. Freezing is not a security boundary when untrusted code can access nested values or other mutable capabilities.

Limitations

  • Object.freeze() only makes the object itself immutable. If the object contains nested objects, those nested objects are not frozen and can still be modified.
  • To deeply freeze an object, you would need to recursively apply Object.freeze() to all nested objects.
const deepFreeze = (value, seen = new WeakSet()) => {
if (
(typeof value !== 'object' && typeof value !== 'function') ||
value === null
) {
return value;
}
if (seen.has(value)) return value;
seen.add(value);
for (const key of Reflect.ownKeys(value)) {
deepFreeze(value[key], seen);
}
return Object.freeze(value);
};
const nestedObj = {
name: 'John',
details: {
age: 30,
address: '123 Street',
},
};
deepFreeze(nestedObj);
nestedObj.details.age = 31; // This will not change the age property
console.log(nestedObj); // Output: { name: "John", details: { age: 30, address: "123 Street" } }

Further reading

Exercises

Check your understanding
Beta
Check your understanding Exercise
Check your understanding Exercise

What does this non-strict code log?

const state = Object.freeze({
count: 1,
nested: { count: 2 },
});
state.count = 3;
state.nested.count = 4;
state.extra = true;
console.log(state.count, state.nested.count, 'extra' in state);