Passing Variables by Value vs Reference in JavaScript

April 10, 2019

arrow pointing in a direction

An important concept to understand in JavaScript (and in many other languages) is passing variables by value vs. by reference.

Passing variables by value happens when assigning primitive values (like numbers, strings, and booleans) to variable.

A new spot in memory is allocated, filled with the given value, and pointed to by the variable name. For example:

const num1 = 5; 

// a new slot in memory is created and filled with the number 5. Now there are two variables, num1

// and num2, that point to two separate instances of the number 5.

const num2 = num1;
 
// so if we do this:

num2++;

//it changes num2, but has no effect on num1.

console.log(num1); // 5

console.log(num2); // 6

Let’s contrast this with passing variables by reference - this is what happens with objects and arrays.

One of the most common issues with passing object references occurs when passing objects into functions.

Let’s say that you start with a dog object named “Buster”:

const buster = {

name: 'Buster',
species : 'dog'

}

You like buster a lot. So much, in fact, that you want to make another dog that will be his twin.

You do this by writing a function:

function makeMyDogATwin(dog){

const newDog = dog;

newDog.name = `${dog.name}'s Twin`;

return newDog;

}

then you invoke the function, excited for your dog’s twin to arrive-

const busterTwin = makeMyDogATwin(buster);

console.log(busterTwin.name) // "Buster's twin"

but wait - let’s see what Buster’s name is now:

console.log(buster.name) // "Buster's twin"

Uh-oh, buster disappeared! Not really. What happened is that since we passed in the buster object by reference, and not by value, we mutated a property on the original object instead of creating a new object with the desired property.

This is an important concept to understand - if ignored, it will lead to all kinds of undesired effects and bugs in your code. Here’s one last example:

let num = 4

let otherNum = num;

 

let numObject = {value: 4};

let otherNumObject = numObject;

 

otherNum ++;

otherNumObject.value++

 

console.log(num)  //4

console.log(otherNum)  //5

console.log(numObject.value)  //5

console.log(otherNumObject.value) //5

So remember, when you pass a primitive value, it creates an entirely new variable. When you pass by reference, it points to the original object or array.


John D Potts

John D Potts

Web developer and speaker in Charlotte, NC.