Course: JavaScript

Progress (0%)

  1. Foundation

  2. Numbers

  3. Strings

  4. Conditions

  5. Loops

  6. Arrays

  7. Functions

  8. Objects

  9. Exceptions

  10. HTML DOM

  11. CSSOM

  12. Events

  13. Drag and Drop

  14. opt Touch Events

  15. Misc

  16. Project: Analog Clock

JavaScript Pass by Value

Chapter 13 12 mins

Learning outcomes:

  1. What is meant by 'passing' values
  2. What is pass-by-value
  3. Passing objects around
  4. There's no pass-by-reference in JavaScript

Introduction

When the time comes to assign, or simply pass, a value to other identifiers in JavaScript, we get to see what's commonly known as pass-by-value.

Surprisingly resources out there tend to introduced another related idea into JavaScript that's truly not supported at all by the language — the idea of pass-by-reference.

Strictly speaking, there is one and only one way to pass values in JavaScript and that's by copying the value, which is essentially what's meant by pass-by-value. Said another way, JavaScript really only supports pass-by-value.

Languages such as PHP, C++, C#, allow one to pass data either by value or by reference; in JavaScript, however there's absolutely no way to pass data by reference (at least as of this writing).

In this chapter, we'll learn all about what exactly is meant by pass-by-value.

What is meant by 'passing'?

Before we can unravel the intuition behind pass-by-value, it's worthwhile being familiar with where this idea pops up in JavaScript.

Basically, whenever we assign an identifier (i.e. variable, constant, property, etc.) to another identifier in JavaScript, we are doing what's concisely referred to as passing the identifier around.

Passing an identifier is just to assign it to another identifier.

For example, if we have a variable x and we assign it to another variable y, we'll say that we're passing the variable x to y.

Similarly, if we provide the variable x to a function f() as an argument, we'll again say that we're passing the variable x but this time to the function f().

'Passing' is just a compact word that means to either assign an identifier to another identifier, or provide it as an argument to a function, or even return a value back from a function.

It's seriously that simple.

What is pass-by-value?

Now, let's make intuition behind the idea of pass-by-value.

Pass-by-value is when we pass an identifier by copying its value.

In pass-by-value, the value stored in the passed identifier is copied and then its copy stored in the other identifier.

Hence, we say 'pass-by-value', that is, we're passing the exact value stored.

Consider the following code:

var text = 'Hello';
var str = text;

text = 'Bye';

console.log(str);

Go over it carefully and think what would be logged in the console and why.

What would the code above log?

Well, the code would log the value 'Hello':

Hello

Let's find out why...

First we define a variable text and initialize it with the value 'Hello'. Then we assign text to a second variable str. Once this is done, we finally alter text and then log str.

Now at this moment one would expect that since text was assigned to str, changing text would cause str to change as well; but this doesn't happen. It's simply because primitives in JavaScript are passed by value.

In the section below, we shall learn that even objects are passed by value.

Applying this to the example above:

When we assign text to str, the actual value stored in text, which is 'Hello', is copied and the copy assigned to str.

In other words, both variables text and str have their own separate 'Hello' values; changing one won't obviously change the other.

So the code above is technically equivalent to the following:

var str = 'Hello'; // own value
var text = 'Hello'; // own value

text = 'Bye';

console.log(str);

As is clear over here, both variables text and str have their own separate values 'Hello'.

Passing objects around

Primitives aren't the only classification of JavaScript's data types right? We have objects too. Now, when objects are passed around, they are too passed by value.

However, the value passed around for objects can sometimes be a source of confusion for newbie developers. Likewise, let's first understand how an object is stored in JavaScript.

In JavaScript, an object is stored inside identifiers by its reference, NOT by its actual value.

A reference could be thought of as a memory address that points to a location where an object is stored.

Since an object in JavaScript is stored inside identifiers by its reference, when the object is passed around, this reference is what actually gets passed.

An object is the real data; a reference is how the object is represented in a program.

Again, it's superbly important to note that objects are still passed just like primitives in JavaScript, i.e. by value; the only thing that's different for objects is how they are stored, i.e. by reference.

(If you've been told that JavaScript passes objects by reference and not by value, note that this statement is incorrect, as we discuss in the next section below.)

Let's consider an example.

Take a look at the following code:

var obj = { x: 10 };
var obj2 = obj;

obj.x = 20;

console.log(obj2.x);

As before, try to guess the output produced.

What would the code above log?

Well, the code would log 20, not 10:

20

Time to find out why...

We start by defining a variable obj with the object value { x: 10 } before defining another variable obj2, initialized to obj. Next, we mutate the property x of obj and then log the same property for obj2.

The mutation of obj.x is visible in obj2 simply because both obj and obj2 refer to the same object in memory. obj and obj2 do NOT hold separate objects — they hold the exact same object.

The following illustration might help visualize this:

How an object is stored in JavaScript
How an object is stored in JavaScript

Here's our obj variable. It contains a value that points to (shown with an arrow) an object { x: 10 } in memory. This value is what we call a reference.

When we assign obj to another variable obj2, here's what happens:

Assigning an object to another identifier in JavaScript
Assigning an object to another identifier in JavaScript

The value stored in obj (which is a reference) is merely copied over into obj2. Hence, obj2 points (shown by the arrow) to the same object { x: 10 } pointed to by obj.

If we now go on and change a property of obj, as we did in the code above by updating the property x, the change would be visible in obj2 as well.

Restating it:

When we assign obj to obj2, the actual value stored in obj, which is a reference, is copied and that copy is assigned to obj2.

Henceforth, if we mutate the object stored in obj (or obj2), the changes would obviously be visible in obj2 (or obj) as well, since they both contain the exact same object.

However, keep in mind that if we write another value to the variable obj or obj2 itself, and NOT to any of its properties, the other variable would NOT change! This is detailed in the following section.

No pass-by-reference in JavaScript!

You might've heard of the term pass-by-reference being used in JavaScript to refer to how objects are passed around, i.e. objects are passed by reference.

If you didn't hear any such thing and are completely new to this idea, well and good. But if you did, and if you're awaiting to know what exactly is pass-by-reference, note that 'pass-by-reference' is precisely somewhat a loose term in JavaScript.

As stated at the start of this chapter, pass-by-reference is a misnomer in JavaScript.

You can NOT really pass an identifier by its reference (in memory) in JavaScript and expect other pieces of code to be able to control what's stored in that identifier.

The source of confusion

What's confusing here, and should be therefore sorted out as soon as possible, is that the term 'reference' in 'pass-by-reference' is not the same thing as the term 'reference' used to refer to how objects are stored in JavaScript.

The concept of pass-by-reference actually comes from other programming languages where we could either provide the actual value stored inside a variable to another variable or provide its reference.

Also, the meaning of reference here differs from language to language.

For instance, in C++, a reference usually refers to a physical location of the variable in memory (more commonly referred to as a pointer); similarly, in PHP a reference refers to a value that is tied to another value (changing one would change the other as well).

Passing a variable by reference in effect means that the variable could be changed from anywhere in the code where that reference is available. That's because we have a reference to the variable in hand, not its underlying value.

As a matter of fact, it's really easy to confirm that pass-by-reference isn't supported in JavaScript in the traditional sense.

Taking the code in the section above as an example, if we reassign any value to obj or to obj2 itself, the other variable would NOT change magically.

Consider the following code:

var obj = { x: 10 };
var obj2 = obj; // This is just pass-by-value.

obj = 20;

console.log(obj2);

Everything is the same here as before except for that now the variable obj is mutated itself (instead of mutating its property x as we did before). Then, obj is logged directly, instead of logging obj.x.

Here's the output produced:

{ x: 10 }

Because there's nothing such as pass-by-reference in JavaScript in the true sense, the moment we assign a value to obj, obj2 doesn't get changed — it keeps holding on to { x: 10 }.

That's purely by virtue of the fact that there's absolutely nothing tying up the two variables obj and obj2 together.

The following illustration might help visualize what's happening in the code above:

Assigning obj, holding an object initially, the value 20
Assigning obj, holding an object initially, the value 20

So, while the term 'pass-by-reference' is commonly used out there, loosely though, it's crucially important for us to appreciate the fact that there isn't truly any such thing in JavaScript.

The term 'pass-by-reference' is purely used for the ease of explaining it to beginners how objects are passed around in JavaScript, i.e. they're passed by their value which is a reference.

But that ease might sometimes backfire and instead confuse learners as to how exactly are objects passed around in JavaScript. For this very reason, we refrain from using the term in that manner.