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:

  1. Value (Primitive types) – The variable holds the actual value.

  2. 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:

  1. Stack Memory (Primitive Values)

    • Used for storing primitive values.

    • Each variable gets its own space in memory.

    • Fast and automatically managed.

  2. 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

FeaturePrimitives (Value)Objects/Arrays (Reference)
StorageStored in stackStored in heap
AssignmentCreates a copyCreates a reference
ModificationDoes not affect originalAffects original object
CopyingDirect copyNeeds 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! 📩🚀