5.7 Values Types VS References Types
JavaScript has two categories of types. On one side we have value types, also called primitives: number, string, boolean, symbol (added in ES6), undefined and null. On the other side we have reference types: objects, functions and arrays — remember that functions and arrays are themselves objects. Primitives and objects behave differently in copies and function calls, and understanding this is essential before moving on to prototypes.
let x = 10;
let y = x; // value copy
x = 20;
console.log(x, y); // 20 10
With primitives, the value is stored directly inside the variable. Assigning y = x copies that value into a brand-new slot, so the two variables are completely independent. With objects it is different:
let x = { value: 10 };
let y = x; // reference copy
x.value = 20;
console.log(y.value); // 20
The same rule applies to function calls
- A primitive passed to a function is copied — mutations inside the function do not affect the caller.
- An object passed to a function is shared — mutating its properties inside the function is visible outside.
function increase(o) { o.value++; }
const num = { value: 10 };
increase(num);
console.log(num.value); // 11
In short: primitives are copied by value, references are copied by reference. Keep this in mind whenever you assign objects or pass them to functions — many bugs come from forgetting that two variables can point to the same underlying object in memory.
Summary
JavaScript has two fundamental type categories: primitive value types (numbers, strings, booleans, symbols, undefined, null) and reference types (objects, functions, arrays). Primitives are copied by their actual value, making independent copies when assigned, while reference types are copied by their memory reference, meaning multiple variables point to the same object. Understanding this distinction is essential for predicting how variable modifications affect other variables and function behavior.
Key points
- Primitive types (value types) are copied by their actual value; modifying one variable does not affect another even if one was initially assigned from the other
- Reference types (objects, functions, arrays) are copied by reference; multiple variables point to the same object in memory, so modifications via any variable are visible to all
- When passing primitives to functions, the value is copied independently, so modifications inside the function do not affect the original variable
- When passing reference types to functions, the reference is passed, meaning modifications to the object affect the original variable outside the function
- Functions and arrays are objects in JavaScript; they follow reference type copying rules, not value type copying
- This behavior difference between primitives and references is foundational for understanding prototypes and advanced JavaScript patterns
FAQ
Why does modifying a primitive variable not affect a copy made from it, but modifying an object does?
Primitives store their actual value in the variable, so copying creates two independent values. Objects store only a reference (memory address) to the actual object elsewhere in memory, so both variables point to the same object. Modifying the object through one reference is visible through all references to that object.
How does this affect function parameters?
When you pass a primitive to a function, its value is copied into the function's local parameter—the original variable remains unchanged. When you pass an object (reference type) to a function, the reference is passed, not a copy, so modifications to that object inside the function affect the original object outside the function.
Are functions and arrays subject to the same rules as other objects?
Yes. In JavaScript, functions and arrays are objects, so they are copied and passed by reference, not by value. Assigning a function or array to another variable creates a second reference to the same underlying function or array.