Understanding Value vs. Reference in JavaScript: Differences Between Primitives and Objects
Have you ever wondered why modifying an array inside a function affects the original array, but modifying a number does not? The reason lies in how JavaScript handles values and references in memory.
Understanding primitives and objects—and how they are stored and manipulated in memory—can help you write more efficient code, avoid unintended bugs, and optimize performance. Let’s break it down.
1. Value vs. Reference in JavaScript
In JavaScript, variables store data in two ways:
Value (Primitive types) – The variable holds the actual value.
Reference (Objects) – The variable holds a reference (memory address) to the actual data.
Let’s explore both in detail.
2. Primitive Types (Stored by Value)
Primitives are the simplest data types in JavaScript:
Number
String
Boolean
Undefined
Null
Symbol
BigInt
How Primitives are Stored in Memory
When you assign a primitive value to a variable, JavaScript stores the value directly in memory at a fixed location.
let a = 10;
let b = a; // Copy the value of `a` into `b`
b = 20; // Changing `b` does not affect `a`
console.log(a); // 10
console.log(b); // 20
Key Takeaway
Each primitive variable has its own copy of the data.
Modifying one variable does not affect the other.
3. Reference Types (Stored by Reference)
Reference types include:
Objects
Arrays
Functions
How Objects are Stored in Memory
Instead of storing the actual value, JavaScript stores a memory reference (address) where the data is located.
let obj1 = { name: "John" };
let obj2 = obj1; // Both variables point to the same object in memory
obj2.name = "Doe"; // Modifying `obj2` affects `obj1`
console.log(obj1.name); // "Doe"
console.log(obj2.name); // "Doe"
Key Takeaway
Objects and arrays are stored by reference, not by value.
Modifying one variable affects all other references to the same object.
4. Memory Allocation in JavaScript
JavaScript manages memory using two areas:
Stack Memory (Primitive Values)
Used for storing primitive values.
Each variable gets its own space in memory.
Fast and automatically managed.
Heap Memory (Reference Types)
Used for storing objects and functions.
Variables store references (pointers) to memory locations.
Slower than stack memory.
let num = 100; // Stored in Stack
let arr = [1, 2, 3]; // Stored in Heap, with `arr` holding a reference
Stack:
num -> 100 (variable num Stores actual value)
Heap:
arr -> [1, 2, 3] (variable arr Stores reference to object in heap)
Visualization of Stack vs. Heap
5. Avoiding Unintended Mutations
Since objects and arrays are stored by reference, unexpected changes can occur.
Solution 1: Copying Objects (Shallow Copy)
To create a separate copy of an object:
let obj1 = { name: "Alice" };
let obj2 = { ...obj1 }; // Spread operator creates a new object
obj2.name = "Bob";
console.log(obj1.name); // "Alice" (remains unchanged)
console.log(obj2.name); // "Bob"
Solution 2: Copying Arrays (Shallow Copy)
let arr1 = [1, 2, 3];
let arr2 = [...arr1]; // Creates a new array
arr2.push(4);
console.log(arr1); // [1, 2, 3]
console.log(arr2); // [1, 2, 3, 4]
6. Deep Copy vs. Shallow Copy
A shallow copy creates a new object but retains references to nested objects. It helps prevent modifications to the original when manipulating the copied object, but it is only effective for non-nested structures.
let obj1 = { name: "Sam", details: { age: 25 } };
let obj2 = { ...obj1 };
obj2.details.age = 30;
console.log(obj1.details.age); // 30 (Unexpected change!)
To fully clone objects, structuredClone
:
let deepCopy2 = structuredClone(obj1); // Better alternative
7. Summary Table: Value vs. Reference
Feature | Primitives (Value) | Objects/Arrays (Reference) |
Storage | Stored in stack | Stored in heap |
Assignment | Creates a copy | Creates a reference |
Modification | Does not affect original | Affects original object |
Copying | Direct copy | Needs deep copy for nested objects |
8. Conclusion
Primitives are stored by value in the stack, meaning each variable gets its own copy.
Objects/arrays in JavaScript are stored in the heap, while a reference to them is kept in the stack. The variable name holds this reference, acting as a pointer to the actual object in the heap.
Use spread operator (
...
) , structuredClone to avoid unwanted mutations.
Understanding value vs. reference is crucial for writing efficient, bug-free JavaScript code!
If you enjoyed this breakdown and want more JavaScript insights, subscribe to my newsletter! 📩🚀