DEV Community

Cover image for The Clone Conspiracy: Shallow Copy vs. Deep Copy in JavaScript πŸ‘―β€β™‚οΈ
kiran ravi
kiran ravi

Posted on

The Clone Conspiracy: Shallow Copy vs. Deep Copy in JavaScript πŸ‘―β€β™‚οΈ

In JavaScript, objects and arrays don't play by the same rules as simple numbers or strings. If you don't understand how they are copied, you’ll end up with "Ghost Mutations"β€”where changing a value in one part of your app mysteriously breaks a value in another.

Let’s break down the difference using real-world architecture rather than food metaphors.


1. The Core Concept: Reference vs. Value

When you copy a Primitive (string, number), JS gives you a real copy.
When you copy an Object or Array, JS gives you a Reference (a pointer to a memory address).


2. The Shallow Copy: "The Shared Folder"

Think of a Shallow Copy like sharing a Google Drive Folder. You create a new "shortcut" to the folder, but the files inside are the exact same ones everyone else is looking at.

Real-Time Example: A User Dashboard
Imagine you have a user object with nested settings. You want to create a "Draft" of the user's settings to see how changes look before saving.

const user = {
  id: 101,
  profile: {
    username: "dev_pro",
    theme: "dark"
  }
};

// Creating a Shallow Copy using the Spread Operator (...)
const userDraft = { ...user };

// Changing a top-level property (Safe)
userDraft.id = 102; 

// Changing a nested property (DANGER!)
userDraft.profile.theme = "light";

console.log(user.profile.theme); // "light" 😱 (The original changed!)

Enter fullscreen mode Exit fullscreen mode

Why it happened: The spread operator only copies the first level. The profile property in both objects still points to the same memory address. You didn't copy the profile; you shared it.


3. The Deep Copy: "The Independent Blueprint"

A Deep Copy is like taking a physical blueprint, putting it in a photocopier, and walking into a different room. Whatever you draw on your copy has zero effect on the original.

Real-Time Example: E-commerce Order History
You have a "Template Order" and you want to create a new "Customer Order" based on it. You need them to be completely separate so the customer doesn't accidentally change the template.

The Modern Solution: structuredClone()

const templateOrder = {
  items: ["Laptop", "Mouse"],
  specs: { warranty: "2 years" }
};

// Creating a True Deep Copy
const customerOrder = structuredClone(templateOrder);

customerOrder.specs.warranty = "1 year";

console.log(templateOrder.specs.warranty); // "2 years" βœ… (Original is safe!)

Enter fullscreen mode Exit fullscreen mode

4. Which Tool to Use? (Comparison Table)

Method Type Best For... Drawbacks
{...obj} Shallow Single-level objects/React state updates. Nested objects stay linked.
[...arr] Shallow Simple lists of strings or numbers. Nested arrays stay linked.
structuredClone() Deep Complex Data / API Responses. Won't copy functions/methods.
JSON.parse/stringify Deep Quick fixes in legacy code. Corrupts Date and undefined.

5. Real-World Engineering Scenarios

Scenario A: React State Immutability

In React, you should never mutate state. If you have a nested state object and you only do a shallow copy, React might not detect the change in the nested object, and your UI won't re-render.
Solution: Use deep copies or specific libraries like Immer to ensure fresh references.

Scenario B: Undo/Redo Functionality

If you are building an editor (like a text editor or a photo app), you need "Snapshots" of the data at different times. If those snapshots are shallow copies, every "Undo" step will be corrupted by the current changes.
Solution: A Deep Copy is required to preserve the state of the data at that specific point in time.


Summary for Developers

  • Use Shallow Copy (...) when your object is "flat" (no objects inside objects) and you want performance.
  • Use Deep Copy (structuredClone) when you are dealing with complex data structures, API results, or configurations where you cannot risk "leaking" changes back to the source.

Top comments (0)