Deep clone
Implement deepClone(value) without structuredClone or JSON (the tests remove both). Copy plain objects, arrays, Date, Map and Set at every depth. Keep functions and primitives as they are. Handle cycles: an object that points to itself must clone to an object that points to the clone. Each test builds a value, clones it, and reports checks that must all be true.
Start from
function deepClone(value) {
// Return a deep copy that shares nothing mutable with the input.
}Hints
Each hint gives away a little more. Open one only when you need it.
Hint 1
Primitives and functions are returned as they are. Date, Map and Set each need their own branch.
Hint 2
For cycles, keep a WeakMap from each original object to its copy, and pass it down the recursion.
Hint 3
Store the copy in the WeakMap before you fill it. Otherwise a cycle recurses forever.
Solution
From here on the page gives the method away. If you are still solving, go back to the hints.
JavaScript
function deepClone(value, seen = new WeakMap()) {
if (typeof value !== "object" || value === null) return value;
if (seen.has(value)) return seen.get(value);
if (value instanceof Date) return new Date(value.getTime());
if (value instanceof Map) {
const copy = new Map();
seen.set(value, copy);
for (const [key, item] of value)
copy.set(deepClone(key, seen), deepClone(item, seen));
return copy;
}
if (value instanceof Set) {
const copy = new Set();
seen.set(value, copy);
for (const item of value) copy.add(deepClone(item, seen));
return copy;
}
const copy = Array.isArray(value) ? [] : {};
seen.set(value, copy);
for (const key of Object.keys(value)) copy[key] = deepClone(value[key], seen);
return copy;
}What an interviewer looks for
The honest first answer is structuredClone. Writing it by hand shows you know what a reference is, which types need care, and how to stop a cycle.