Freeze protects an object’s own properties but does not recursively freeze nested values. Immutability must account for the whole data graph.
Step-by-step walkthrough
Step 1: Identify the protected object
Freeze operates on one object’s own properties. Draw nested references and distinguish replacing a property from mutating its referenced object. This is the same ownership distinction candidates need for shallow copying and immutable updates.
Step 2: Choose graph-wide discipline
If the API requires deeper immutability, establish immutable values, recursive protection with cycle handling or disciplined updates. Special built-in collections and accessors require attention; a generic object walk is not automatically a correct deep-freeze contract.
Step 3: Verify through aliases
A frozen object can still be observed through multiple references. Check whether a second owner can mutate nested data and whether getters expose mutable state. TypeScript readonly annotations are separate compile-time restrictions and do not perform runtime freezing.
Worked scenario
Freezing {settings: {theme: 'light'}} does not stop changing the nested theme.
const config = Object.freeze({
retry: {count: 2}
});
config.retry.count = 3;
console.log(config.retry.count); // 3
const protectedRetry = Object.freeze({count: 2});
const safer = Object.freeze({retry: protectedRetry});
console.log(Object.isFrozen(safer.retry)); // trueWalk through the example
The first outer freeze does not protect retry.count. The second version separately freezes the nested object before sharing it. This small graph has no cycles and no mutable collection entries; more general graphs need a deliberate policy rather than assuming the example handles every value type.
Common mistake
Freezing Map or Set objects does not prevent their entry mutation methods. Cycles complicate recursive freezing.
Verify the behavior
Test outer replacement and nested mutation separately in strict mode. Include an alias to the nested object so the test does not only mutate through the top-level reference. If Maps or Sets are supported, test entry mutation rather than only Object.isFrozen.
Interview exercise
Assess an immutable API claim.
Answer and reasoning
Check nested objects, collection behavior and accessors; combine clear ownership with immutable update rules instead of assuming shallow protection suffices.
Follow-up discussion
Is Object.isFrozen proof of deep immutability? It reports one object’s property state. When are immutable updates preferable? They preserve previous snapshots and meaningful identities without attempting to freeze arbitrary resources or every value in a graph.
Continue learning
Compare the scenario with the JavaScript interview questions and test your understanding with the JavaScript MCQs. For terminology and implementation details, consult the reference material.