Back to roots: JavaScript Value vs Reference

Let’s look at the concept of Value vs Reference. Every JavaScript developer should know this topic as it’s often the reason behind bugs in today’s applications. Also, it’s often one of the job interview questions.

I will cover the basics as easily as I can in this short article.

Don’t scroll down too quickly. Do you know what these two examples return?

console.log([10] === [10]);

var oldArray = [];
var object = {};
object.newArray = oldArray;
oldArray.push(10);
console.log(object.newArray === oldArray);

The first one is false and second one is true. Was your answer right? Let’s look at why.


In JavaScript we have types that are copied by value and types copied by reference. These are

Primitives (copied by value)

  • null
  • undefined
  • Number
  • String
  • Boolean

Objects (copied by reference)

  • Object
  • Array
  • Function

Primitives

var a = 5;
var b = a;
a = 10;
console.log(a); // 10
console.log(b); // 5
// this is also true for string, boolean, null, undefined

When we assign primitives to the variable, we copy the value.

Objects

Now, the confusing part.

var a = {};
var b = a;
a.a = 1;
console.log(a); // {a: 1}
console.log(b); // {a: 1}

This is also true for Arrays

var a = [];
var b = a;
a.push(1);
console.log(a); // [1]
console.log(b); // [1]
console.log(a === b); // true

When we assign Objects (non-primitives) to the variable, we copy them by reference. You can imagine, that by declaring a variable we create new address in memory. When we declare variable b it just points to this address. So when we update the content of this address, both variable a and b have the same value.

var a = [];     # Address #001 -> []
# Variable a -> #001
var b = a;      # Variable b -> #001
a.push(1);      # Address #001 -> [1]
Variable | Address | Value
a | #011 | [1]
b | #011 | [1]

Now, about the [10] === [10] example

When we compare Objects, equality operator (===) will check if they point to the same address. So if [10] and [10] are two different arrays, the result will be false as in the last example. When you want to compare values of two arrays or objects there is a simple, but limited solution.

JSON.stringify(a) === JSON.stringify(b)

Although it will return false if properties of both objects/arrays are not in the same order. If you want more robust solution you can use lodash _.isEqual() method. Or implement your own solution as described in this stackoverflow answer.

Conclusion

There is more to cover about this topic. I will probably write more articles about pure/impure functions, immutability, how to create copy of object/array so original variable is not changed, etc... So clap for this article and let me know that I should :) Also don’t forget to follow me to be notified.