Shallow vs Deep Copy
⚠️ The Copy Problem in JavaScript
JavaScript objects are copied by reference, not by value. Understanding different copy methods is crucial to avoid bugs and unexpected mutations.
Visualizing Copy Types
Reference Copy
const a = {x: 1};
const b = a; // Reference
b.x = 2;
console.log(a.x); // 2 🚨Both point to same object
Shallow Copy
const a = {x: 1, y: {z: 2}};
const b = {...a}; // Shallow
b.y.z = 3;
console.log(a.y.z); // 3 🚨Top-level copied, nested referenced
Deep Copy
const a = {x: 1, y: {z: 2}};
const b = deepCopy(a);
b.y.z = 3;
console.log(a.y.z); // 2 ✓Complete independent copy
Example 1: The Problem with References
JavaScript Editor
🔍 Why This Matters
Common Bug Scenarios
- Modifying state in React/Vue without proper copying
- Accidentally mutating configuration objects
- Sharing data between components/functions
- Caching or memoization bugs
- Race conditions in async code
Real Impact
- Hard-to-debug state corruption
- Security issues with shared data
- Performance problems from unintended mutations
- Testing failures due to shared state
- Concurrency issues in web workers
Example 2: Shallow Copy Methods
JavaScript Editor
✅ When Shallow Copy is Enough
- Objects with only primitive values
- When nested objects are immutable
- React state updates (with spread operator)
- Configuration objects without nested structures
- Performance-critical code paths
- When you want to share nested references
❌ When Shallow Copy Fails
- Objects with nested objects/arrays
- When complete isolation is needed
- Sending data to web workers
- Caching/memoization implementations
- Undo/redo functionality
- Immutable state management
Example 3: Deep Copy Methods
JavaScript Editor
📊 Deep Copy Method Comparison
| Method | Functions | Dates | RegExp | Circular Refs | Maps/Sets | Symbols | Performance |
|---|---|---|---|---|---|---|---|
JSON.parse(JSON.stringify()) | ❌ Lost | ❌ String | ❌ Object | ❌ Error | ❌ Lost | ❌ Lost | Fast |
structuredClone() | ❌ Lost | ✅ Preserved | ✅ Preserved | ✅ Works | ✅ Preserved | ✅ Preserved | Medium |
| Custom Implementation | ✅ Preserved | ✅ Preserved | ✅ Preserved | ✅ Works | ✅ Preserved | ✅ Preserved | Slow |
Lodash _.cloneDeep() | ✅ Preserved | ✅ Preserved | ✅ Preserved | ✅ Works | ✅ Preserved | ✅ Preserved | Medium |
Example 4: Performance and Use Cases
JavaScript Editor
⚡ Performance Guidelines
Small Objects (< 100 props)
Any method works. Choose based on features needed.
Medium Objects (100-1000 props)
Avoid custom recursive deep copy. Use structuredClone() or libraries.
Large Objects (> 1000 props)
Consider shallow copy or immutable data structures.
Memory Considerations
- Deep copies use 2x memory (temporarily)
- Shallow copies use minimal extra memory
- Consider copy-on-write patterns
- Use object pooling for frequent copies
CPU Considerations
- JSON methods are fastest for serializable data
structuredClone()is optimized in browsers- Custom functions are slowest but most flexible
- Avoid deep copies in hot loops
Example 5: Special Cases and Edge Cases
JavaScript Editor
Exercise: Implement Copy Utilities
JavaScript Editor
💡 Best Practices Summary
- Default to shallow copy unless you need deep copy
- Use
structuredClone()when available and appropriate - Avoid
JSON.parse(JSON.stringify())for complex objects - Consider using immutable data structures for frequently copied data
- Use libraries like Lodash for production deep copying
- Always test edge cases: circular refs, special objects, large data
- Document your copy strategy in team projects
- Consider performance implications in hot code paths
🎯 Interview Questions on Copying
- What's the difference between shallow and deep copy?
- How does
Object.assign()differ from spread operator for copying? - What are the limitations of
JSON.parse(JSON.stringify())? - How would you handle circular references in deep copy?
- What is
structuredClone()and when would you use it? - How do you copy an array of objects deeply?
- What are the performance implications of different copy methods?
- How would you implement an immutable update pattern?
- What's the difference between copy and clone in JavaScript?
- How do you handle copying of class instances?