Object.freeze
Introduction
Object.freeze(obj) is JavaScript's built-in way to make an object's top-level shape and top-level data properties immutable. It prevents new properties, prevents deleting or reconfiguring existing properties, and makes existing data properties non-writable.
The key interview phrase is shallow freeze: nested objects are still mutable unless they are frozen too.
Why This Matters
Object.freeze appears in state-management discussions, library API design, and output-prediction questions. Knowing the exact descriptor changes helps you avoid the common but wrong answer that freeze makes a whole object graph deeply immutable.
Theory
What Object.freeze does
Freezing an object performs three top-level operations:
- Prevents extensions, so new own properties cannot be added.
- Marks existing own properties as
configurable: false, so they cannot be deleted or reconfigured. - For existing data properties, marks
writable: false, so assignment cannot change their values.
What it does not do
It does not recursively freeze nested objects. If a frozen object has a property whose value is another object, that nested object can still be changed unless it is also frozen. It also does not make private engine internals disappear, and accessor properties may still compute changing values if their getter reads mutable external state.
Strict mode caveat
Attempting to write to a frozen data property throws in strict mode and is ignored in sloppy mode. Use descriptor inspection, Object.isFrozen, or Reflect.defineProperty examples when you need output that is independent of strict-mode configuration.
Freeze vs const
const protects a variable binding. Object.freeze protects an object's top-level own properties. They solve different problems and are often used together: const config = Object.freeze({ mode: 'prod' }).
When to use it
Freeze is useful for constants, configuration objects, defensive library boundaries, and teaching immutability. It is not a complete replacement for immutable data structures or disciplined copy-on-write updates in large state trees.
Visual Diagrams
frozen config
+------------------------------+
| theme: 'dark' | locked top-level data property
| nested: -------------------- | ----+
+------------------------------+ |
v
nested object
+------------------+
| compact: false | still mutable
+------------------+The outer object is frozen; the nested object is a separate object with its own descriptors.
Code Examples
Inspect what freeze changes
A frozen object's data properties become non-writable and non-configurable, and the object becomes non-extensible.
Nested objects are not frozen automatically
The reference stored in settings.nested is locked at the top level, but the nested object itself remains mutable.
Playground
Press Run to execute the code and see output here.
Output Prediction
Predict the output #1
1const inner = { count: 0 };2const frozen = Object.freeze({ inner: inner });3 4inner.count += 1;5frozen.inner.count += 1;6 7console.log(frozen.inner.count);8console.log(Object.isFrozen(frozen));9console.log(Object.isFrozen(frozen.inner));Predict the output #2
1const obj = Object.freeze({ a: 1 });2const added = Reflect.defineProperty(obj, 'b', {3 value: 24});5 6console.log(added);7console.log(Object.keys(obj).join(','));8console.log(Object.getOwnPropertyDescriptor(obj, 'a').writable);Coding Exercises
Write a simple deepFreeze
MediumImplement deepFreeze(value) for plain acyclic objects and arrays. It should recursively freeze nested objects before returning the original value.
Interview Questions
1What exactly does `Object.freeze` do?
It prevents extensions, marks existing own properties as non-configurable, and marks existing data properties as non-writable. It is shallow: nested objects are not frozen automatically. Writes to frozen data properties throw in strict mode and are ignored in sloppy mode.
Follow-ups
- How is it different from `const`?
- How would you implement a deep freeze?
2Does freezing an object make arrays inside it immutable?
No. The property that points to the array is locked on the frozen object, but the array object itself is separate. You must freeze the nested array too if you need it to be immutable.
Quiz
1. Which statement about `Object.freeze` is true?
2. What does `Object.isFrozen(obj)` check?
Summary
- `Object.freeze` prevents extensions and locks existing own properties at the top level.
- Existing data properties become non-writable and non-configurable.
- Freeze is shallow; nested objects remain mutable unless frozen separately.
- `const` protects a binding, while `Object.freeze` protects object properties.
Cheat Sheet
Freeze means: non-extensible + own properties non-configurable + data properties non-writable.
Check: Object.isFrozen(obj)
Shallow: nested objects are not automatically frozen.
Mode caveat: failed assignments throw in strict mode and are ignored in sloppy mode.
Use for: constants, configs, defensive boundaries, interview immutability questions.