JavaScript pass by value vs pass by reference

The behavior of how JavaScript assigns values to variables is confusing for new developers.

This is because JavaScript passes values to variables by value or reference.

In this article, I attempt to help new developers understand this in the simplest way possible.

Let’s talk about pass by value

Consider a simple value assignment in JavaScript

const firstName = "Ugochukwu";

This statement passes the term Ugochukwu to the constant firstName.

If I create another constant and assign Ugochukwu to it.

const nameOfSomeOneIknow = "Ugochukwu";

I can use firstName and nameOfSomeOneIknow interchangeably throughout my code, and my code will not behave in an unusual way as a result of this.

console.log(firstName === nameOfSomeOneIKnow);
// expected output: true

This comparison or similar ones will always be true because we are passing a value to the constants every time.

Now we can define passing by value as passing a tangible or something concrete. In this case, we are passing a string type to the constants.

JavaScript primitive types

In JavaScript, a string is an example of a primitive value type and primitive value types are not immutable. There are other primitive value types in JavaScript, and they are:

  • Boolean type

  • Null type

  • Undefined type

  • Number type

  • BigInt type

  • String type

  • Symbol type //not covered in this tutorial

These are simple examples of each of the primitive value types:

const isClear = false; // boolean
const nullishly = null; // null
const amICool = undefined; // undefined
const lenghtOfTruck = 34; // number
const scientificValue = 9007199254740992n; // bigInt
const myName = "Ugochukwu"; // string

The other value type in Javascript is the object value type.

And that is where pass by reference comes in.

Now we would talk about pass by reference

We would spend some time on this because there are different threads to pick.

Consider another simple value assignment.

const obj1 = { name: "Ugochukwu" };
const obj2 = { name: "Ugochukwu" };

console.log(obj1 === obj2);
// expected output: false

const obj3 = {};
const obj4 = {};
console.log(obj3 === obj4);
// expected output: false

Hold on to your applause or insults for a few minutes 🤓, let me explain.

In our pass by value example, as far as the value on the right of the assignment is the same when we compare our constants, it always returns true.

In passing by reference it fails, because when we assign our constants to an object, even if the object contains values, the object is not tangible or concrete. It is a reference. We simply assign our constant to the location of the object in memory, not the “actual” object. Therefore no two or more objects assigned to constants or variables this way will be the same because they will be assigned to different locations in memory.

That is a mouth full 🤣.

Let us consider yet another simple value assignment.

const obj = { name: "Ugochukwu" };
const obj1 = obj;
const obj2 = obj;

console.log(obj1 === obj2);
// expected output: true

Now let us take a look at this image 🙏, before we continue our explanation.

Pass by value, pass by reference illustration created with https://app.diagrams.net/

Pass by value, pass by reference illustration created with https://app.diagrams.net/

The image above shows what happens during value assignment.

Figure 1, is pass by value, which has been explained above.


Figure 2, is a classic pass by reference, from our illustration, we can see that objects are stored in a memory location. And any comparison between two objects created independently will return false`, because the memory location cannot be the same.


Figure 3, is even more interesting, we assigned the object to a first constant obj. Then assign that constant to two other constants, obj1 and obj2. When we compare obj1 and obj2, it returns true, because obj1 and obj2 are assigned to the same constant, which in turn is assigned to the memory location.

We have deliberately skipped talking about how objects types are saved in memory beyond the random memory location, because is is not important for this article.

JavaScript object types

Now that we know how javascript handles assignment in object types, we can list the object types we have. They are:

  • Objects

  • Arrays

See simple examples below.

// objects
const emptyUser = {};
const user = { name: "Ugochukwu", age: 30, hobbies: ["Running", "Reading"] };

// arrays
const listOfNothing = [];
const livableCities = ["New York", "London"];

Arrays and objects are passed by reference.

Summary

In terms of variable or constant assignment, you can differentiate JavaScript data types by primitive and object types. With primitive being passed by values, and object types being passed by reference. Below is an easy-to-remember table for this.

Types that passed by valueTypes that are passed by reference
BooleanObject
NullArray
Undefined
Number
BigInt
String

There are more complex threads under passing value by reference, we shall explore those in another article.