Cloning Proxy-wrapped objects with _.cloneDeep in Lodash 4.x: expected behavior vs observed outcome
0 reputation · 13 Mar 2020, 13:42 UTC
0 reputation · 13 Mar 2020, 13:42 UTC
Determine whether Lodash 4.x's _.cloneDeep produces a truly detached copy when the source value includes Proxy‑wrapped objects, functions, DOM nodes, or WeakMap entries.
Because the algorithm treats uncloneable values as plain objects and does not invoke Proxy traps, it is unclear whether the resulting clone retains any behavioral link to the original handler, and whether treating the output as a security boundary for capability‑bearing data such as expired credentials is safe.
Does _.cloneDeep replace a Proxy with an empty plain object or preserve its target? Does the clone retain any internal reference to the original Proxy's handler? Should teams consider the cloned output a safe data boundary for security‑sensitive payloads, or must they rebuild Proxy‑wrapped objects manually?
_.cloneDeep in Lodash 4.x does not preserve a Proxy. It treats the Proxy as a plain object, iterates its enumerable string-keyed properties (triggering get traps during iteration), recursively clones those values, and returns a brand-new plain object. The result has no internal reference to the original handler — no traps fire after the clone.
cloneableTags list, it falls through to the plain-object cloning path.
Object.prototype.toString.call(clone) === '[object Object]')._.cloneDeep returns the exact same reference.Teams should not consider the cloned output a safe data boundary for security-sensitive payloads (such as expired credentials). Because the Proxy is replaced by a plain object, any behavior enforced by the handler (revocation, validation, membrane semantics) is lost. The clone is a data-only snapshot of the Proxy's surface at clone time, but any nested object references remain shared.
To verify this in a modern environment (Node 18+ or browser):
get and has traps._.cloneDeep(proxy) and verify the result is a plain object.If your application requires Proxy-wrapped logic or security membranes, you must rebuild Proxy-wrapped objects manually or use a custom cloner that preserves the Proxy identity and handler logic.
Does your Proxy target contain nested objects that the handler also wraps or mediates? If yes, those nested objects are shared by reference in the clone, revoking the original Proxy may leave the clone holding stale or now-unmediated capabilities.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.