Compile Ready
Module 14 · Machine Coding

Build: Deep Clone

Advanced14m read45m practice59m total
Machine CodingObjectsRecursionWeakMap

Introduction

Deep clone means creating a new object graph with the same values but no shared nested object references. A production-quality answer handles arrays, objects, dates, regexes, maps, sets, symbols, property descriptors, and cycles.

The key idea is to recursively clone objects while remembering already-cloned references in a WeakMap.

Why This Matters

Deep clone tests whether you understand references, prototypes, descriptors, cyclic graphs, and built-in types. It is also a gateway to discussing when not to clone: structural sharing, immutable updates, and structuredClone are often better in production.

Theory

Shallow vs deep

A shallow copy duplicates the outer object but keeps nested references. A deep clone recursively duplicates nested objects so changes to the clone do not mutate the original.

Cycle handling

Object graphs can contain cycles: node.self = node. Naive recursion loops forever. Store every source object in a WeakMap before cloning children. If you see the same source again, return the existing clone.

Built-in types

Dates and regexes need custom constructors. Maps clone both keys and values. Sets clone values. Plain objects should preserve their prototype and property descriptors where possible. Functions are usually returned by reference because cloning executable code and closures is not meaningful.

Production note

Modern environments provide structuredClone for many cloneable values, including cycles, Map, Set, Date, ArrayBuffer, and more. It does not clone functions or DOM nodes.

Visual Diagrams

Cycle-safe cloning
clone(object A)
   |
   v
WeakMap: A -> cloneA
   |
   v
clone children
   |
   +--> child points back to A
          |
          v
       return cloneA instead of recursing forever

Register the clone before descending into children.

Code Examples

Complete cycle-safe deep clone

This implementation handles common built-ins and preserves descriptors for objects.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1function deepClone(value, seen) {
2 if (value === null || typeof value !== 'object') {
3 return value;
4 }
5
6 var cache = seen || new WeakMap();
7
8 if (cache.has(value)) {
9 return cache.get(value);
10 }
11
12 var result = Array.isArray(value) ? [] : {};
13 cache.set(value, result);
14
15 Object.keys(value).forEach(function (key) {
16 result[key] = deepClone(value[key], cache);
17 });
18
19 return result;
20}
21
22var original = { nested: { count: 1 } };
23original.self = original;
24var copy = deepClone(original);
25copy.nested.count = 7;
26console.log(original.nested.count);
27console.log(copy.self === copy);

Coding Exercises

Implement a cycle-safe deep clone

Hard

Implement deepClone(value).

Requirements:

  • Return primitives as-is.
  • Clone arrays and objects recursively.
  • Preserve object prototypes where practical.
  • Preserve property descriptors for normal objects.
  • Handle cycles using WeakMap.
  • Clone Date, RegExp, Map, and Set.
  • Preserve symbol keys.
  • Functions may be returned by reference.

Constraints:

  • Do not use JSON serialization.
  • Do not use native structuredClone for the exercise solution.

Interview Questions

1Why is `JSON.parse(JSON.stringify(obj))` not a good deep clone?

It drops functions, undefined, symbols, Date identity, Map, Set, prototypes, descriptors, and fails on cycles. It also changes values such as NaN and Infinity in ways that can be surprising.

Asked at:GoogleAmazon

Follow-ups

  • When is `structuredClone` appropriate?
  • How would you preserve shared references?
2Why use `WeakMap` instead of `Map` for cycle tracking?

A WeakMap lets source objects be garbage-collected when cloning is done and avoids accidentally extending object lifetimes. It also accepts only objects as keys, which is exactly what the clone cache needs.

Quiz

1. When should the source object be stored in the clone cache?

Summary

  • Deep clone copies an object graph, not just the outer object.
  • Use `WeakMap` to handle cycles and preserve shared references.
  • Built-ins such as Date, RegExp, Map, and Set need custom handling.
  • `structuredClone` is often the production choice, but knowing the implementation is interview-critical.

Cheat Sheet

Deep clone checklist

  • Primitives return as-is.
  • Functions usually return by reference.
  • Use WeakMap cache before descending.
  • Date: new Date(time).
  • RegExp: source, flags, lastIndex.
  • Map: clone keys and values.
  • Set: clone values.
  • Object: preserve prototype and descriptors.
  • Use Reflect.ownKeys for symbols and non-enumerables.
  • Avoid JSON for serious cloning.