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.

8 minute lesson

~~~

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 that’s not a primitive type 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

But 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

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

Spread syntax creates a shallow copy:

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

Nested objects are still shared. Use structuredClone() for supported data when a deep independent copy is genuinely required, but do not clone by habit; copying large object graphs has a cost and can hide unclear ownership.

Try it: pass an object with a nested settings object to a function. Mutate a top-level property, mutate the nested property, then reassign the parameter. Predict which changes the caller sees.

Lesson completed