FossilsðŸ’ŧ CodingImplement Deep Clone
ðŸĶ–DinosaurJavaScriptData Structures

Implement Deep Clone

Deep cloning tests understanding of JavaScript data structures, reference types, and edge cases like circular references.

Implement Deep Clone

Looks simple, but the edge cases are what separate juniors from seniors.

Naive Version

const clone = JSON.parse(JSON.stringify(obj));

Problems: Loses functions, undefined, Symbols, Dates (become strings), RegExp, Maps, Sets. Crashes on circular references.

Production Version

function deepClone(value, seen = new WeakMap()) {
  if (value === null || typeof value !== 'object') return value;
  if (value instanceof Date) return new Date(value.getTime());
  if (value instanceof RegExp) return new RegExp(value.source, value.flags);
  if (value instanceof Map) {
    const map = new Map();
    seen.set(value, map);
    value.forEach((v, k) => map.set(deepClone(k, seen), deepClone(v, seen)));
    return map;
  }
  if (value instanceof Set) {
    const set = new Set();
    seen.set(value, set);
    value.forEach((v) => set.add(deepClone(v, seen)));
    return set;
  }
 
  if (seen.has(value)) return seen.get(value);
 
  const clone = Array.isArray(value) ? [] : Object.create(Object.getPrototypeOf(value));
  seen.set(value, clone);
 
  for (const key of Reflect.ownKeys(value)) {
    const descriptor = Object.getOwnPropertyDescriptor(value, key);
    if (descriptor) {
      Object.defineProperty(clone, key, {
        ...descriptor,
        value: deepClone(descriptor.value, seen),
      });
    }
  }
 
  return clone;
}

Key Points

  1. Circular references — WeakMap tracks visited objects to break cycles
  2. Special types — Date, RegExp, Map, Set each need specific handling
  3. Symbol keys — Reflect.ownKeys captures them unlike Object.keys
  4. Prototype chain — Object.create(Object.getPrototypeOf()) preserves it
  5. Property descriptors — preserves getters, setters, and non-enumerable properties

Modern Alternative

const clone = structuredClone(value);

structuredClone handles circular references, most built-in types, and is the modern standard. But it still can't clone functions, DOM nodes, or property descriptors.

The best answer acknowledges structuredClone exists, then demonstrates you understand the underlying mechanics by implementing it manually.