# Mastering Deep Copy vs Shallow Copy in JavaScript: A Must-Know for Developers

When we work with objects and arrays in JavaScript, we often need to copy data. But copying in JavaScript is not always as simple as it looks. Depending on the method you use, you may end up with **shared references** which can cause unexpected changes in your data. To handle this properly, it’s important to understand the concepts of **shallow copy** and **deep copy**.

---

## Shallow Copy

A **shallow copy** creates a new object but only copies the top-level properties.

* If the property is a primitive value like string, number, boolean, null, undefined, symbol, or bigint, it gets copied directly.
    
* If the property is an object, array, or function (reference type), then only the reference is copied. This means both the original and the copied object will point to the same nested structure.
    

### Example:

```
const original = {
  name: "Pratik",
  skills: ["JavaScript", "React"]
};

const shallowCopy = { ...original };

shallowCopy.name = "Alex";
shallowCopy.skills.push("Node.js");

console.log(original.name);   // "Pratik" → unchanged
console.log(original.skills); // ["JavaScript", "React", "Node.js"] → changed
```

Here, the primitive property `name` is copied safely, but the `skills` array is shared. Updating `shallowCopy.skills` also updates `original.skills`.

### Common Ways to Create Shallow Copies:

* Object spread: `{ ...obj }`
    
* `Object.assign({}, obj)`
    
* Array methods like:
    
    * `arr.slice()`
        
    * `[...arr]`
        

---

## Deep Copy

A **deep copy** goes one step further. It copies not only the top-level properties but also all nested objects and arrays. This makes the copied object completely independent of the original.

### Example:

```
const original = {
  name: "Pratik",
  skills: ["JavaScript", "React"]
};

// Deep copy using structuredClone
const deepCopy = structuredClone(original);

deepCopy.name = "Alex";
deepCopy.skills.push("Node.js");

console.log(original.name);   // "Pratik" → safe
console.log(original.skills); // ["JavaScript", "React"] → safe
```

Here, the `deepCopy` object is fully independent. Any change in `deepCopy` does not affect `original`.

### Common Ways to Create Deep Copies:

1. **structuredClone()** (works in modern browsers and Node.js 17+)
    
    ```
    const clone = structuredClone(obj);
    ```
    
2. **JSON method** (works but has limitations)
    
    ```
    const clone = JSON.parse(JSON.stringify(obj));
    ```
    
    Note: This method removes functions, symbols, undefined values, and fails with circular references.
    
3. **Libraries** like Lodash (`_.cloneDeep(obj)`) or Immer.
    

---

## When Should You Use Each?

* **Shallow Copy** is enough when:
    
    * You only need to copy simple, top-level data.
        
    * You are sure that nested objects or arrays will not be modified.
        
* **Deep Copy** is necessary when:
    
    * You want complete independence between the copy and the original.
        
    * You are working with frameworks like React/Redux, where immutability is important.
        
    * You are dealing with nested or complex data structures.
        

---

## Quick Comparison

| Feature | Shallow Copy | Deep Copy |
| --- | --- | --- |
| Copies primitives | Yes | Yes |
| Copies references | Yes (shared) | No (independent) |
| Performance | Faster | Slower |
| Use case | Simple, flat objects/arrays | Nested or complex objects |

---

## Conclusion

Understanding the difference between shallow copy and deep copy is very important for every JavaScript developer. It helps avoid unexpected bugs, especially when handling state management in frameworks like React.

* Use **shallow copy** when you only need a quick top-level copy.
    
* Use **deep copy** when you want complete isolation between the original and the copied data.
    

This clarity will save you from a lot of hidden issues in real-world applications.
