Copying and combining objects is extremely common. The tricky part is understanding when you’re copying references vs making a truly independent copy.
Shallow Cloning with Spread and Object.assign
Shallow cloning copies top‑level properties, but nested objects are still shared by reference.
const original = { a: 1, nested: { x: 10 } };
// Two ways to make a shallow copyconst clone1 = { ...original };const clone2 = Object.assign({}, original);
clone1.a = 2; // changes only clone1.aclone1.nested.x = 99; // changes nested object, shared with original
console.log(original.a); // 1 (primitive copied by value)console.log(original.nested.x); // 99 (object shared by reference)console.log(clone2.nested.x); // 99 (same nested object as original)Shallow clones are great when you only need to copy one level deep, or when nested objects are intentionally shared.
Deep Cloning
Deep cloning creates a fully independent copy, including nested objects.
For JSON‑safe data (no functions, Dates, Maps, etc.), you can use JSON.parse(JSON.stringify(...)):
const user = { name: 'Ada', settings: { theme: 'dark', showToc: true, },};
const deepClone = JSON.parse(JSON.stringify(user));
deepClone.settings.theme = 'light';
console.log(user.settings.theme); // "dark"console.log(deepClone.settings.theme); // "light"For more complex data, modern environments support structuredClone:
const complex = { createdAt: new Date(), items: new Map([ ['a', 1], ['b', 2], ]),};
const copy = structuredClone(complex);
console.log(copy.createdAt instanceof Date); // trueconsole.log(copy.items instanceof Map); // trueMerging Objects
Merging is combining properties from multiple objects into a new one, often used for configuration.
const defaults = { theme: 'light', showToc: true, pageSize: 10 };const userConfig = { theme: 'dark', pageSize: 20 };
// Later spreads override earlier onesconst effective = { ...defaults, ...userConfig };
console.log(effective);// { theme: 'dark', showToc: true, pageSize: 20 }For nested objects, merge nested levels explicitly to avoid losing properties.
const defaultUser = { name: '', settings: { theme: 'light', layout: 'single-column', },};
const incoming = { name: 'Ada', settings: { theme: 'dark', },};
const mergedUser = { ...defaultUser, ...incoming, settings: { ...defaultUser.settings, ...incoming.settings, },};
console.log(mergedUser.settings);// { theme: 'dark', layout: 'single-column' }Object.freeze and Object.seal
Object.freeze makes an object immutable at the top level: you cannot add, remove, or change its properties.
const config = { env: 'prod', debug: false };
Object.freeze(config);
config.debug = true; // ignored or throws in strict modeconfig.newKey = 'x'; // ignoreddelete config.env; // ignored
console.log(config); // { env: 'prod', debug: false }Be aware that freeze is shallow: nested objects can still be mutated.
const frozen = Object.freeze({ nested: { x: 1 } });
// Still allowed because nested object itself is not frozenfrozen.nested.x = 42;
console.log(frozen.nested.x); // 42Object.seal is similar, but you can still change existing values:
const sealed = { a: 1 };
Object.seal(sealed);
sealed.a = 2; // OKsealed.b = 3; // ignoreddelete sealed.a; // ignored
console.log(sealed); // { a: 2 }Deep Freezing Helper
To truly freeze an entire object graph, recursively freeze all nested objects.
function deepFreeze(obj) { // Freeze properties before freezing self Object.getOwnPropertyNames(obj).forEach((name) => { const value = obj[name]; if (value && typeof value === 'object') { deepFreeze(value); } }); return Object.freeze(obj);}
const settings = deepFreeze({ ui: { theme: 'dark', density: 'comfortable' }, api: { url: 'https://api.example.com' },});
// All these mutations will be ignored or throw in strict modesettings.ui.theme = 'light';settings.api.url = 'https://evil.com';
console.log(settings.ui.theme); // "dark"console.log(settings.api.url); // "https://api.example.com"Understanding shallow vs deep cloning, merging, and immutability is critical when working with stateful code (like React apps, Redux stores, or any shared application state).