Shallow copying copies only the top level properties of an object. If properties contain other objects, only references to them are copied. Deep copying copies all nesting levels, creating a completely independent copy.
The difference between shallow and deep copying is one of the important topics in JavaScript. Understanding this difference helps avoid many mistakes.
Copies only the first level properties:
const original = {
name: 'John',
address: { city: 'Moscow' }
};
const shallow = { ...original };
// shallow.name — copy
// shallow.address — reference to the same object!Copies all nesting levels:
const original = {
name: 'John',
address: { city: 'Moscow' }
};
const deep = structuredClone(original);
// deep.name — copy
// deep.address — also copy, new objectconst user = {
name: 'John',
address: { city: 'Moscow' }
};
const shallow = { ...user };
shallow.address.city = 'Piter';
console.log(user.address.city); // 'Piter' — original object changed!const user = {
name: 'John',
address: { city: 'Moscow' }
};
const deep = structuredClone(user);
deep.address.city = 'Piter';
console.log(user.address.city); // 'Moscow' — original object not changed// Working with forms
const defaultForm = {
user: { name: '', age: 0 },
settings: { theme: 'light' }
};
// Shallow copy — dangerous!
const form1 = { ...defaultForm };
form1.user.name = 'John';
// Now defaultForm.user.name is also 'John'!
// Deep copy — safe
const form2 = structuredClone(defaultForm);
form2.user.name = 'Peter';
// defaultForm unchanged// Spread operator
const shallow1 = { ...original };
// Object.assign
const shallow2 = Object.assign({}, original);// structuredClone (modern way)
const deep1 = structuredClone(original);
// JSON methods (with limitations)
const deep2 = JSON.parse(JSON.stringify(original));// Shallow — fast
const shallow = { ...obj };
// Deep — slower, especially for large objects
const deep = structuredClone(obj);// JSON methods lose functions, undefined, Symbol
const obj = { func: () => {}, undef: undefined };
const copy = JSON.parse(JSON.stringify(obj));
// copy.func and copy.undef will disappear!
// structuredClone preserves all types
const copy2 = structuredClone(obj);
// All data preserved// ❌ Using shallow for nested objects
const config = { database: { host: 'localhost' } };
const copy = { ...config };
copy.database.host = 'remote';
console.log(config.database.host); // 'remote' — unexpected!
// ✅ Using deep copying
const copy2 = structuredClone(config);
copy2.database.host = 'remote';
console.log(config.database.host); // 'localhost' — correct// ❌ JSON methods don't work with functions
const obj = { method: () => {} };
const copy = JSON.parse(JSON.stringify(obj));
// copy.method will disappear!
// ✅ Using structuredClone
const copy2 = structuredClone(obj);
// All data preservedUnderstanding the difference between shallow and deep copying helps write predictable code and avoid reference errors.
Want more articles to prepare for interviews? Subscribe to EasyAdvice, bookmark the site and improve yourself every day 💪