Objects

Are values passed by reference or by value in JavaScript?

Are values passed by reference or by value in JavaScript? Primitive types pass by value while objects pass by reference, as these examples show.

JavaScript always passes arguments by value. The confusing part is that an object’s value is a reference to that object.

Primitive types are numbers, strings, booleans, null, undefined and symbols.

Everything else is an object. Arrays are objects. Functions are objects.

Passing a primitive copies that primitive value:

const increment = num => {
  num = num + 1
}

const num = 2
increment(num)

console.log(num) //2

Passing an object copies the reference. The caller and parameter now point at the same object, so a property mutation is visible through both names:

const increment = num => {
  num.value = num.value + 1
}

const num = {
  value: 2
}

increment(num)

console.log(num.value) //3

Reassigning the parameter only changes its local copy of the reference:

function replace(value) {
  value = { count: 0 }
}

const state = { count: 2 }
replace(state)
console.log(state.count) // 2

Saying “objects are passed by reference” is a shortcut. If JavaScript passed the variable itself by reference, replace() would make state point at the new object.

Think of a variable holding an object as holding a sticky note with an address. Passing the note to a function copies the note, not the house. Everyone with a copy of the note visits the same house.

Reassigning the parameter writes a new address on your copy only. Mutating a property redecorates the shared house.

Spread syntax creates a shallow copy:

const next = { ...state, count: 3 }

Nested objects are still shared. Use structuredClone() when you need a deep independent copy, but do not clone by habit. Large graphs cost memory and can hide ownership.

Arrays follow the same rule. Mutating via a copied reference changes the shared array:

const first = [1, 2]
const second = first
second.push(3)
console.log(first.length) // 3

Use [...arr] or Array.from(arr) when you need a shallow copy before passing data into a function that might mutate.

Pass an object with a nested settings object to a function. Mutate a top-level property, mutate the nested property, then reassign the parameter. Log the caller’s object after each step and note what changed.

Lesson completed