Immutability Helper - Problem
The Immutability Challenge

In modern JavaScript development, immutability is a cornerstone principle that prevents unexpected side effects and makes code more predictable. However, creating modified copies of complex nested objects can be tedious and error-prone.

Your task is to implement an ImmutableHelper class that provides a clean, intuitive API for creating modified copies of immutable objects. The class should:

• Accept any JSON object or array in its constructor
• Provide a produce method that takes a mutator function
• Return a new object with changes applied, while keeping the original untouched
• Use JavaScript Proxy to create an illusion of direct mutation

Example:
const originalObj = {x: 5, nested: {y: 10}};
const helper = new ImmutableHelper(originalObj);
const newObj = helper.produce((proxy) => {
  proxy.x = proxy.x + 1;
  proxy.nested.y = 20;
});
console.log(originalObj); // {x: 5, nested: {y: 10}} - unchanged!
console.log(newObj);      // {x: 6, nested: {y: 20}} - modified copy

The mutator function receives a proxied version of the object that tracks all changes without affecting the original. Your implementation must handle nested objects and arrays while maintaining immutability.

Input & Output

basic_mutation.js — Basic Property Change
$ Input: const originalObj = {x: 5, y: 10}; const helper = new ImmutableHelper(originalObj); const newObj = helper.produce((proxy) => { proxy.x = proxy.x + 1; });
Output: originalObj: {x: 5, y: 10} newObj: {x: 6, y: 10}
💡 Note: The proxy intercepts the assignment to `proxy.x` and creates a new object with the modified value while keeping the original unchanged.
nested_mutation.js — Nested Object Modification
$ Input: const originalObj = {user: {name: 'John', age: 30}, count: 5}; const helper = new ImmutableHelper(originalObj); const newObj = helper.produce((proxy) => { proxy.user.age = 31; proxy.count = 6; });
Output: originalObj: {user: {name: 'John', age: 30}, count: 5} newObj: {user: {name: 'John', age: 31}, count: 6}
💡 Note: The proxy handles nested object access by creating proxies for nested objects, allowing deep mutations while preserving immutability of the original structure.
array_mutation.js — Array Modification
$ Input: const originalArr = [1, 2, {value: 3}]; const helper = new ImmutableHelper(originalArr); const newArr = helper.produce((proxy) => { proxy[0] = 10; proxy[2].value = 30; });
Output: originalArr: [1, 2, {value: 3}] newArr: [10, 2, {value: 30}]
💡 Note: Arrays are handled just like objects, with array indices treated as properties. The proxy creates new arrays and objects only for the paths that are modified.

Constraints

  • The input object will be a valid JSON object or array
  • The mutator function will always return undefined
  • The mutator will never access non-existent keys
  • The mutator will never delete keys or call methods on objects
  • The original object must never be modified
  • Maximum object depth: 100 levels
  • Maximum number of properties per object: 1000

Visualization

Tap to expand
Rootx: 5nestedy: 10New Rootx: 6nestedCopy-on-Write StrategyOriginal (Immutable)ResultShared Reference (Memory Efficient)🎯 Key Benefits✓ Original stays immutable✓ Memory efficient sharing✓ Lazy copying strategy✓ Deep nesting support✓ Transparent proxy API✓ Optimal performance
Understanding the Visualization
1
Original Object Tree
Start with the original immutable object structure
2
Proxy Wrapper
Wrap the object in a Proxy that intercepts all property access
3
Mutation Detection
When a property is modified, create a copy-on-write for that path
4
Structural Sharing
Unchanged parts of the object tree are shared between original and result
Key Takeaway
🎯 Key Insight: JavaScript Proxy enables transparent immutability by intercepting mutations and applying copy-on-write semantics, creating efficient immutable updates with minimal memory overhead.
Asked in
Meta 45 Google 38 Netflix 32 Airbnb 28
24.7K Views
Medium Frequency
~35 min Avg. Time
892 Likes
Ln 1, Col 1
Smart Actions
💡 Explanation
AI Ready
💡 Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen