This repository demonstrates the difference between shallow and deep copy in JavaScript, along with a practical solution using the Immer library for immutable state management. Understanding how objects are copied in JavaScript can help prevent unexpected bugs, especially when dealing with nested data structures.
- Shallow Copy vs Deep Copy
- Why Does This Happen?
- Deep Copy Using Immer
- Installation
- Usage
- Examples
- License
In JavaScript, copying objects is a common task, but there are key differences between shallow and deep copying:
A shallow copy creates a new object, but nested objects or arrays are still referenced. Changes to nested structures affect both the original and copied object.
Example:
const obj1 = { name: "Wireless Mouse", address: { city: "Dhaka" } };
const obj2 = { ...obj1 };
obj2.address.city = "Khulna"; // Affects obj1 too!
console.log(obj1.address.city); // Output: Khulna
A deep copy duplicates the entire object, including nested objects. Changes to one object do not affect the other.
Example:
const obj1 = { name: "Wireless Mouse", address: { city: "Dhaka" } };
const obj2 = JSON.parse(JSON.stringify(obj1)); // Deep copy
obj2.address.city = "Khulna"; // Does not affect obj1
console.log(obj1.address.city); // Output: Dhaka
This behavior is due to how JavaScript handles objects:
- Shallow copy: Copies only the top-level properties. Nested objects remain references.
- Deep copy: Creates a fully independent copy, including nested structures.
Immer is a modern JavaScript library that makes working with immutable data structures easier by allowing you to make immutable updates with a simple API. With Immer, deep copies can be done effortlessly without manually managing nested objects.
import produce from "immer";
const obj1 = {
name: "Wireless Mouse",
address: { city: "Dhaka", country: "Bangladesh" }
};
// Using Immer to create a deep copy and modify the object immutably
const obj2 = produce(obj1, (draft) => {
draft.address.city = "Khulna";
});
console.log(obj1.address.city); // Output: Dhaka (unchanged)
console.log(obj2.address.city); // Output: Khulna (updated)
To get started with this project, you need to clone the repository and install the required dependencies:
git clone https://github.com/yourusername/immer-shallow-deep-copy.git
cd immer-shallow-deep-copy
npm install
-
Clone the repository:
git clone https://github.com/yourusername/immer-shallow-deep-copy.git
-
Install dependencies:
npm install
-
Run the example or integrate the solution into your project:
import produce from "immer"; const obj1 = { name: "Wireless Mouse", address: { city: "Dhaka" } }; const obj2 = produce(obj1, (draft) => { draft.address.city = "Khulna"; }); console.log(obj1.address.city); // Dhaka console.log(obj2.address.city); // Khulna
const obj1 = { name: "Keyboard", address: { city: "Dhaka" } };
const obj2 = { ...obj1 };
obj2.address.city = "Khulna";
console.log(obj1.address.city); // Output: Khulna (due to shallow copy)
console.log(obj2.address.city); // Output: Khulna
import produce from "immer";
const obj1 = { name: "Keyboard", address: { city: "Dhaka" } };
const obj2 = produce(obj1, (draft) => {
draft.address.city = "Khulna";
});
console.log(obj1.address.city); // Output: Dhaka (unchanged)
console.log(obj2.address.city); // Output: Khulna (updated)
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
Shallow and deep copying in JavaScript are fundamental concepts that you should be aware of when working with objects and arrays. While shallow copies are faster, deep copies are essential when you need to ensure full independence between objects. Immer is an excellent tool to help with immutability, making deep copying simple and efficient.