3. Implement deepClone(obj) — Handle Cycles, Maps, Sets, Dates

hard

This question separates candidates who know JavaScript from those who think they do. The trap is overconfidence — most candidates write a 6-line recursive copy and miss every edge case.

The five things to handle

  1. Primitives — return as-is.
  2. Cycles — use a WeakMap to remember objects you've seen.
  3. Arrays vs plain objectsArray.isArray first.
  4. Built-insDate, Map, Set, RegExp need their own constructors.
  5. Symbols and non-enumerable keysReflect.ownKeys if the interviewer pushes.

Reference solution

function deepClone(value, seen = new WeakMap()) {
  if (value === null || typeof value !== "object") return value;
  if (seen.has(value)) return seen.get(value);

  if (value instanceof Date) return new Date(value);
  if (value instanceof RegExp) return new RegExp(value.source, value.flags);

  if (value instanceof Map) {
    const out = new Map();
    seen.set(value, out);
    value.forEach((v, k) => out.set(deepClone(k, seen), deepClone(v, seen)));
    return out;
  }

  if (value instanceof Set) {
    const out = new Set();
    seen.set(value, out);
    value.forEach((v) => out.add(deepClone(v, seen)));
    return out;
  }

  const out = Array.isArray(value) ? [] : {};
  seen.set(value, out);
  for (const key of Reflect.ownKeys(value)) {
    out[key] = deepClone(value[key], seen);
  }
  return out;
}

"Why not just structuredClone?"

Good question to ask back. structuredClone works for most data but throws on functions and DOM nodes, and isn't available in all runtimes. Interviewers ask this question specifically to see if you can write the algorithm — saying "I'd use structuredClone" gets you out of the easy version but never the hard one.

More questions

index.js
function deepClone(value, seen = new WeakMap()) {
  // your code here
}

const a = { x: 1, nested: { y: 2 } };
a.self = a; // cycle
const b = deepClone(a);
console.log(b.nested !== a.nested); // true
console.log(b.self === b);          // true

Tests

Test Code

Enter JavaScript that runs after your solution. It should return a value or a Promise.