Compile Ready
Module 6 · Objects & Prototypes

Object.freeze

Intermediate9m read6m practice15m total
Object.freezeImmutabilityDescriptorsShallow

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:

  1. Prevents extensions, so new own properties cannot be added.
  2. Marks existing own properties as configurable: false, so they cannot be deleted or reconfigured.
  3. 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

Freeze is shallow
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.

Loading…

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.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
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

javascript
1const obj = Object.freeze({ a: 1 });
2const added = Reflect.defineProperty(obj, 'b', {
3 value: 2
4});
5
6console.log(added);
7console.log(Object.keys(obj).join(','));
8console.log(Object.getOwnPropertyDescriptor(obj, 'a').writable);

Coding Exercises

Write a simple deepFreeze

Medium

Implement 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.

Asked at:MetaMicrosoftAmazon

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.

Asked at:GoogleNetflix

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.