Ever wanted to deep-copy any JavaScript object, even those with circular references? Here’s a magical utility function that does just that. Perfect for copying state in complex apps, or just wowing your friends!
/**
* Deeply clones a value, including objects with circular references!
* @param {any} value - The value to deep clone.
* @param {WeakMap} [seen=new WeakMap()] - Internal map to track circular references.
* @returns {any} - The deeply cloned value.
*/
function deepClone(value, seen = new WeakMap()) {
if (typeof value !== 'object' || value === null) return value;
if (seen.has(value)) return seen.get(value);
let clone;
if (Array.isArray(value)) {
clone = [];
seen.set(value, clone);
for (const item of value) {
clone.push(deepClone(item, seen));
}
} else if (value instanceof Date) {
clone = new Date(value);
} else if (value instanceof RegExp) {
clone = new RegExp(value.source, value.flags);
} else {
clone = {};
seen.set(value, clone);
for (const [key, val] of Object.entries(value)) {
clone[key] = deepClone(val, seen);
}
}
return clone;
}
// --- Usage Example ---
const a = { foo: 'bar' };
a.self = a; // Circular reference!
const b = deepClone(a);
console.log(b); // { foo: 'bar', self: [Circular] }
console.log(b !== a); // true
console.log(b.self === b); // true- Handles arrays, objects, dates, regexes, and circular references.
- No external dependencies—pure JavaScript!
- Great for advanced state management, undo-redo, or serialization tricks.
Fork, star, and share your own magical utilities!