Question presented to candidate: "Write a deep clone function that correctly copies nested objects and arrays, and does not stack-overflow or infinite-loop if the input contains a cycle — for example an object with a property that points back to itself, or two objects that reference each other. How do you make sure the CLONE'S cycle points back to the new clone, not back to the original object?"
What a strong answer should cover:
- The core mechanism is a
seenmap (aWeakMapfrom original object references to their already-created clones) checked at the very top of the recursive function, before recursing into any of that object's properties. - The clone for an object must be registered in the
seenmap BEFORE recursing into its properties, not after — otherwise a cycle that leads back to the object currently being cloned would not find it in the map yet, and infinite recursion would still happen. - When a cycle is hit, the function returns the ALREADY-CREATED (but possibly still-being-populated) clone object reference from the map, not a brand-new one and not the original.
- A
WeakMap(over a plainMap) is the right choice here because it does not prevent the original objects from being garbage collected once cloning is done and the map itself goes out of scope. - Special object types —
Date,RegExp,Map,Set— need explicit handling, since a naive property-copy loop would not correctly reconstruct them as real instances of those types. - Primitives (numbers, strings, booleans,
null,undefined, symbols) are returned as-is — cloning is only meaningful for objects and arrays, which are the only things that can participate in a reference cycle in the first place.
Clarifying questions expected:
- "Does the clone need to preserve property descriptors (getters, non-enumerable flags), or is a plain value copy of own enumerable properties acceptable?" — a real fidelity trade-off, since preserving descriptors means using
Object.definePropertyandReflect.ownKeysinstead of a simplefor...in-style copy. - "Do class instances need to keep their prototype/constructor, or is a plain object clone acceptable even for class instances?" — determines whether
Object.create(Object.getPrototypeOf(value))is needed for the fallback case.
Code / implementation expected: Yes — a full, runnable deep clone using a WeakMap seen-set, plus a real test proving a self-referencing object clones without hanging or throwing, and that the clone's cycle points to the new clone, not the original.