Problem Statement
Explain the difference between shallow copy and deep copy. How do you create each in JavaScript?
Explanation
Shallow copy creates a new object but copies only the top level properties. Nested objects are still referenced, not copied. Changes to nested objects affect both original and copy.
Deep copy creates a completely independent copy. All nested objects are also copied recursively. Changes to the copy do not affect the original at any level.
Creating shallow copies:
Use spread operator, Object assign, or Array slice. These are fast but only copy one level deep. Nested objects remain shared between original and copy.
Creating deep copies:
Use JSON parse and JSON stringify for simple objects without functions, dates, or special types. Use structured clone for more complete copying including dates and typed arrays. Use libraries like Lodash cloneDeep for complex objects. Write custom recursive function for specific needs.
When to use each:
Use shallow copy when objects are flat or you want to share nested references for performance. Use deep copy when you need complete independence and do not want any shared references.
Common pitfalls:
JSON methods lose functions, undefined, symbols, and dates. Shallow copies can cause unexpected mutations. Deep copying is slower and uses more memory.
Understanding the difference is crucial for avoiding bugs when working with complex data structures.
Code Solution
SolutionRead Only
// SHALLOW COPY
const original = {
name: 'John',
age: 30,
address: {city: 'NYC', zip: '10001'}
};
// Method 1: Spread operator
const shallow1 = {...original};
// Method 2: Object.assign
const shallow2 = Object.assign({}, original);
// Top level is copied
shallow1.name = 'Jane';
console.log(original.name); // 'John' (unchanged)
// Nested objects are referenced
shallow1.address.city = 'LA';
console.log(original.address.city); // 'LA' (changed!)
// Array shallow copy
const arr = [1, 2, [3, 4]];
const arrCopy = [...arr];
arrCopy[2][0] = 99;
console.log(arr[2][0]); // 99 (changed!)
// DEEP COPY
// Method 1: JSON (simple objects only)
const deep1 = JSON.parse(JSON.stringify(original));
deep1.address.city = 'Boston';
console.log(original.address.city); // 'NYC' (unchanged!)
// JSON limitations
const complex = {
name: 'John',
greet: function() {}, // Lost!
date: new Date(), // Becomes string
undef: undefined // Lost!
};
const jsonCopy = JSON.parse(JSON.stringify(complex));
console.log(jsonCopy.greet); // undefined (function lost)
// Method 2: structuredClone (modern)
const deep2 = structuredClone(original);
deep2.address.city = 'Chicago';
console.log(original.address.city); // 'NYC' (unchanged!)
// Method 3: Custom recursive function
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof Array) return obj.map(item => deepClone(item));
const cloned = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloned[key] = deepClone(obj[key]);
}
}
return cloned;
}
const deep3 = deepClone(original);
deep3.address.city = 'Miami';
console.log(original.address.city); // 'NYC' (unchanged!)