Deep Cloning JavaScript Objects with Lodash _.cloneDeep
Learn how to safely deep‑clone nested JavaScript objects with Lodash’s _.cloneDeep, preserving Dates, Maps, Sets and circular references while keeping the original intact.
17 Jul 2026, 15:50 UTC

Desired Outcome
Create an independent copy of a nested JavaScript object so that modifications to the copy do not affect the original, while preserving special values like Dates, Maps, Sets and handling circular references.
Prerequisites
- Node.js >=12 installed
- Access to a terminal or Node REPL
- Ability to install npm packages (or use a CDN in the browser)
Procedure
- Install Lodash (if not already present):
npm install lodash@4.17.21 - Import the
cloneDeepfunction in your script:const _ = require("lodash"); // or ES6: import cloneDeep from "lodash/cloneDeep"; - Define a source object that includes nested arrays, objects, a Date, a Map, a Set and a circular reference:
const source = { name: 'example', stats: { score: 5, tags: ['a', 'b'] }, created: new Date(), metadata: new Map([['key', 'value']]), tagsSet: new Set([1, 2, 3]), }; // Introduce a circular reference source.self = source; - Perform the deep clone:
const clone = _.cloneDeep(source); - Verify that the clone is independent:
- Modify a primitive in the clone and confirm the source is unchanged:
clone.stats.score = 99; console.log(source.stats.score); // expected: 5- Change a Date in the clone and ensure the source Date retains its original timestamp:
clone.created.setFullYear(2000); console.log(source.created.getFullYear()); // expected: current year (not 2000)- Confirm that circular reference does not cause an error and that the clone's
selfproperty points to the clone itself:
console.log(clone.self === clone); // expected: true console.log(source.self === source); // expected: true (original unchanged)
Expected Checks
- No
RangeErrororMaximum call stack size exceededis thrown during the_.cloneDeepcall. - After mutation, the source object’s properties remain identical to their pre‑clone values.
- Special values (Date, Map, Set) are instances of their respective constructors in the clone, not plain objects.
Limitations and Practical Verification
Deep cloning large structures can consume considerable memory; monitor process memory if cloning objects >10 MB. Functions are not duplicated – they are shared by reference. If you need to preserve class prototypes, consider a custom cloning strategy or a library that supports prototype preservation.
To check memory impact, run Node with the --inspect flag and observe heap usage before and after cloning, or use process.memoryUsage():
const before = process.memoryUsage().heapUsed;
const clone = _.cloneDeep(largeObject);
const after = process.memoryUsage().heapUsed;
console.log(`Heap increase: ${after - before} bytes`);
Recovery Options
Because _.cloneDeep does not mutate the source, no rollback is required. If you discover that the clone is unnecessarily large, you can discard it and revert to a shallow copy (_.clone) or manual selective copying for performance‑critical paths.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.