Difficulty: Intermediate
What are the different ways to clone objects in JavaScript? What are the limitations of each?
Cloning approaches:
1. Spread/Object.assign: shallow copy only - nested objects still share references 2. JSON.parse(JSON.stringify()): deep clone but loses functions, undefined, Symbol, Date objects (converted to strings), circular references (throws) 3. structuredClone() (modern): true deep clone, supports Date, Map, Set, ArrayBuffer, RegExp, circular references. Does NOT clone functions or DOM nodes. 4. Custom recursive clone: complete control but adds complexity 5. Libraries: lodash cloneDeep, immer (structural sharing)
const original = {
name: 'Alice',
scores: [1, 2, 3],
address: { city: 'Mumbai' }
};
const shallow = { ...original };
shallow.name = 'Bob';
shallow.scores.push(4);
shallow.address.city = 'Delhi';
console.log(original.name);
console.log(original.scores);
console.log(original.address.city);
const jsonClone = JSON.parse(JSON.stringify(original));
jsonClone.scores.push(99);
console.log(original.scores);
Spread only copies the top level. JSON clone creates truly independent nested objects but has limitations with special types.
const withSpecials = {
date: new Date(),
fn: () => 'hello',
undef: undefined,
map: new Map([['key', 'val']])
};
const jsonClone = JSON.parse(JSON.stringify(withSpecials));
console.log(typeof jsonClone.date);
console.log(jsonClone.fn);
console.log(jsonClone.map);
const obj = {
date: new Date('2024-01-01'),
arr: [1, 2, 3],
nested: { x: 10 }
};
const clone = structuredClone(obj);
clone.nested.x = 99;
clone.arr.push(4);
console.log(obj.nested.x);
console.log(obj.arr);
console.log(clone.date instanceof Date);
const circular = { name: 'test' };
circular.self = circular;
const circClone = structuredClone(circular);
console.log(circClone.self === circClone);
structuredClone is the recommended modern approach. It handles Dates, Maps, Sets, circular references, and preserves types correctly.
Deep Clone, structuredClone, JSON.parse, Shallow Copy, Spread