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.