References, Copying & structuredClone
Stop accidentally mutating data! Learn how variables point to objects in memory, and how to safely copy them without causing side effects.
Passed by Value vs Reference
In JavaScript, primitive types (numbers, strings, booleans) are passed by **value**. If you copy a string into a new variable, you get a completely separate duplicate.
Objects and Arrays are passed by **reference**. When you assign an object to a new variable, you aren't copying the data-you are just creating a new arrow that points to the exact same memory location.
The Mutation Trap
Because variables just hold 'pointers' to the underlying object, modifying one variable will affect all others that point to the same object.
If user1 = { name: 'Bob' } and user2 = user1, then changing user2.name = 'Alice' will also change user1!
Shallow vs Deep Copying
To avoid the mutation trap, you must explicitly copy the object.
**Shallow Copy** (using { ...obj }): Creates a new top-level object, but if your object contains nested objects or arrays, those inner structures are still passed by reference.
**Deep Copy** (using structuredClone(obj)): Creates a 100% independent clone. Absolutely nothing is shared in memory.
The Clone Visualizer
Compare Assignment (=), Shallow Copy ({...}), and Deep Copy (structuredClone) to see exactly how memory pointers are shared or detached.
The Clone Visualizer
Check yourself
Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.
Remember this
- Primitives are passed by value; Objects and Arrays are passed by reference.
- Assigning an object to a new variable just creates a new pointer to the same data.
- A Shallow Copy (
{...obj}) duplicates the top level, but shares nested objects. - A Deep Copy (
structuredClone(obj)) duplicates everything recursively, severing all ties.
Done with this concept?
Mark it complete to track your progress. No login needed.