|
| 1 | +### **What is the Difference Between Shallow Copy and Deep Copy ?** |
| 2 | + |
| 3 | +When working with objects or arrays in programming, it’s important to understand the concepts of **shallow copy** and **deep copy**. These concepts determine how data is copied from one object or array to another and how changes to the original data affect the copied data. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +### **Shallow Copy** |
| 8 | + |
| 9 | +A **shallow copy** creates a new object or array, but it only copies the reference of nested objects or arrays. This means that if the original data contains other objects or arrays, the shallow copy will still reference the same memory location for those nested objects or arrays. |
| 10 | + |
| 11 | +#### **Characteristics:** |
| 12 | + |
| 13 | +1. Copies only the top-level properties. |
| 14 | +2. Does not duplicate nested objects or arrays; instead, it references them. |
| 15 | +3. Changes made to nested objects or arrays in the original will reflect in the shallow copy (and vice versa). |
| 16 | + |
| 17 | +#### **Examples of Shallow Copy:** |
| 18 | + |
| 19 | +1. **Using `Object.assign()` (for objects):** |
| 20 | + |
| 21 | +```javascript |
| 22 | +const original = { name: "Alice", details: { age: 25 } }; |
| 23 | +const shallowCopy = Object.assign({}, original); |
| 24 | + |
| 25 | +shallowCopy.name = "Bob"; // Changes only the copy |
| 26 | +shallowCopy.details.age = 30; // Changes the original's nested object too |
| 27 | + |
| 28 | +console.log(original.details.age); // Output: 30 |
| 29 | +``` |
| 30 | + |
| 31 | +2. **Using the Spread Operator (for objects and arrays):** |
| 32 | + |
| 33 | +```javascript |
| 34 | +const originalArray = [1, 2, { a: 3 }]; |
| 35 | +const shallowCopyArray = [...originalArray]; |
| 36 | + |
| 37 | +shallowCopyArray[2].a = 10; // Changes the original nested object |
| 38 | +console.log(originalArray[2].a); // Output: 10 |
| 39 | +``` |
| 40 | + |
| 41 | +--- |
| 42 | + |
| 43 | +### **Deep Copy** |
| 44 | + |
| 45 | +A **deep copy** creates a new object or array and recursively copies all levels of nested objects or arrays. This means that the copied data is completely independent of the original data. |
| 46 | + |
| 47 | +#### **Characteristics:** |
| 48 | + |
| 49 | +1. Duplicates all nested structures. |
| 50 | +2. The copy is independent of the original; changes to one do not affect the other. |
| 51 | +3. More computationally expensive compared to a shallow copy. |
| 52 | + |
| 53 | +#### **Examples of Deep Copy:** |
| 54 | + |
| 55 | +1. **Using `JSON.parse(JSON.stringify())`:** |
| 56 | + |
| 57 | +```javascript |
| 58 | +const original = { name: "Alice", details: { age: 25 } }; |
| 59 | +const deepCopy = JSON.parse(JSON.stringify(original)); |
| 60 | + |
| 61 | +deepCopy.details.age = 30; // Changes only the copy |
| 62 | +console.log(original.details.age); // Output: 25 |
| 63 | +``` |
| 64 | + |
| 65 | +**Note:** This method does not handle special cases like functions, `undefined`, `Date`, or circular references. |
| 66 | + |
| 67 | +2. **Using a Utility Library like Lodash:** |
| 68 | + |
| 69 | +```javascript |
| 70 | +const _ = require("lodash"); |
| 71 | + |
| 72 | +const original = { name: "Alice", details: { age: 25 } }; |
| 73 | +const deepCopy = _.cloneDeep(original); |
| 74 | + |
| 75 | +deepCopy.details.age = 30; // Changes only the copy |
| 76 | +console.log(original.details.age); // Output: 25 |
| 77 | +``` |
| 78 | + |
| 79 | +3. **Manual Recursion:** |
| 80 | + |
| 81 | +```javascript |
| 82 | +function deepCopy(obj) { |
| 83 | + if (obj === null || typeof obj !== "object") { |
| 84 | + return obj; |
| 85 | + } |
| 86 | + |
| 87 | + const copy = Array.isArray(obj) ? [] : {}; |
| 88 | + for (let key in obj) { |
| 89 | + copy[key] = deepCopy(obj[key]); |
| 90 | + } |
| 91 | + return copy; |
| 92 | +} |
| 93 | + |
| 94 | +const original = { name: "Alice", details: { age: 25 } }; |
| 95 | +const deepCopyObj = deepCopy(original); |
| 96 | + |
| 97 | +deepCopyObj.details.age = 30; // Changes only the copy |
| 98 | +console.log(original.details.age); // Output: 25 |
| 99 | +``` |
| 100 | + |
| 101 | +--- |
| 102 | + |
| 103 | +### **Key Differences Between Shallow Copy and Deep Copy** |
| 104 | + |
| 105 | +| Feature | Shallow Copy | Deep Copy | |
| 106 | +| ------------------------- | -------------------------------------- | ------------------------------------------------------------- | |
| 107 | +| **Copies Top-Level Data** | Yes | Yes | |
| 108 | +| **Copies Nested Data** | No (references nested objects) | Yes (creates independent copies) | |
| 109 | +| **Original-Dependent** | Changes in nested data affect the copy | Changes in nested data do not affect | |
| 110 | +| **Performance** | Faster and less memory-intensive | Slower and more memory-intensive | |
| 111 | +| **Methods** | `Object.assign()`, Spread Operator | `JSON.parse(JSON.stringify())`, Recursive Function, Libraries | |
| 112 | + |
| 113 | +--- |
| 114 | + |
| 115 | +### **When to Use** |
| 116 | + |
| 117 | +- **Shallow Copy:** |
| 118 | + Use when you are dealing with simple data structures where nested objects are not modified independently. |
| 119 | + |
| 120 | +- **Deep Copy:** |
| 121 | + Use when working with complex data structures and need to ensure that the copy is completely independent of the original. |
| 122 | + |
| 123 | +--- |
| 124 | + |
| 125 | +### **Conclusion** |
| 126 | + |
| 127 | +Understanding the difference between shallow copy and deep copy is crucial for managing data in JavaScript effectively. While shallow copies are faster and sufficient for simple scenarios, deep copies are indispensable when dealing with deeply nested data structures that require complete independence from the original object or array. |
0 commit comments