FossilsðŸ’ŧ CodingImplement Deep Clone
ðŸĢHatchlingJavaScriptUtilityData Structures

Implement Deep Clone

Deep cloning reveals your knowledge of JavaScript's type system, circular references, and the edge cases that break naive implementations.

Implement Deep Clone

Interview Question: "Implement a deep clone function that handles nested objects, arrays, and circular references."

Level 1: Basic (Handles Objects & Arrays)

function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
 
  if (Array.isArray(obj)) {
    return obj.map(item => deepClone(item));
  }
 
  const clone = {};
  for (const key of Object.keys(obj)) {
    clone[key] = deepClone(obj[key]);
  }
  return clone;
}

Level 2: With Circular Reference Handling

function deepClone(obj, seen = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (seen.has(obj)) return seen.get(obj);
 
  let clone;
 
  if (Array.isArray(obj)) {
    clone = [];
    seen.set(obj, clone);
    obj.forEach((item, i) => { clone[i] = deepClone(item, seen); });
  } else if (obj instanceof Date) {
    clone = new Date(obj.getTime());
  } else if (obj instanceof RegExp) {
    clone = new RegExp(obj.source, obj.flags);
  } else if (obj instanceof Map) {
    clone = new Map();
    seen.set(obj, clone);
    obj.forEach((val, key) => clone.set(deepClone(key, seen), deepClone(val, seen)));
  } else if (obj instanceof Set) {
    clone = new Set();
    seen.set(obj, clone);
    obj.forEach(val => clone.add(deepClone(val, seen)));
  } else {
    clone = Object.create(Object.getPrototypeOf(obj));
    seen.set(obj, clone);
    for (const key of Reflect.ownKeys(obj)) {
      clone[key] = deepClone(obj[key], seen);
    }
  }
 
  return clone;
}

Key points:

  • WeakMap for seen — Detects circular references, doesn't leak memory
  • Type-specific handling — Date, RegExp, Map, Set need special construction
  • Reflect.ownKeys — Gets string AND symbol keys
  • Object.getPrototypeOf — Preserves prototype chain

The Modern Answer: structuredClone

const clone = structuredClone(original);

structuredClone (available in all modern browsers + Node 17+) handles:

  • Nested objects, arrays, Date, RegExp, Map, Set, ArrayBuffer, Blob
  • Circular references
  • Error objects

Does NOT clone: Functions, DOM nodes, Symbols, property descriptors, prototype chain.

Senior move: Start with structuredClone, then explain when you'd need a custom implementation (functions, custom classes, property descriptors).

Common Mistakes

  • Not handling circular references (infinite recursion)
  • Using JSON.parse(JSON.stringify()) — loses Date, RegExp, undefined, functions, circular refs
  • Forgetting Map/Set
  • Using for...in (includes inherited properties)