Value vs Reference Assignment in JavaScript

In my opinion, value vs reference assignment is an important topic that many JS beginners don’t stop and think about enough.

Let’s test your knowledge of this concept with some puzzles.

Puzzle #1:

This first puzzle is part of Douglas Crockford’s function challenges. You can watch some of his exercises in the free video sample at FrontEndMasters.

What is x?

function funky(o) {
  o = null;

var x = [];

o is a parameter of funky. This means that it is a local variable of funky. What gets passed to funky? Is it a reference of x or is it just whatever value that x is (an empty array)? It is in fact passed by value. o is an empty array that knows nothing of variable x. This local variable o is then set to null which has no effect on variable x. [] is alerted.

Puzzle #2:

Lets try another. What is x?

function funky2(o) {

var x = [1,2,3,4];

The answer is [2,3,4,5]. JavaScript does pass by value but this “value” is itself a reference. Confusing? Let’s take a deeper look.

This stackoverflow answer by Nick Rabinowitz explains this well.

“Changing the value of a variable never changes the underlying primitive or object, it just points the variable to a new primitive or object. However, changing a property of an object referenced by a variable does change the underlying object.”

Lets look at our first puzzle again. We changed the value of a variable, o. This had no effect on the underlying object, []. It just pointed the variable o to a new primitive, null. For more information on primitives, check out my post Type Checking in JS.

With our second puzzle, we passed [1,2,3,4], by value, into our function. We used two array methods, shift and push which changed the internal properties of our object, [2,3,4,5], which was referenced by variable o. Our underlying object was changed which is the object that x points to. x is now [2,3,4,5].

Puzzle #3:

One more puzzle. This is a variation on this stackoverflow answer.

What is obj1? What is obj2?

function foo(bar, baz) {
  bar.changed = true;
  baz = {changed: true};

var obj1 = {
  changed: false

var obj2 = {
  changed: false

foo(obj1, obj2);

We are changing a property on the object referenced by variable bar. The underlying object is changed. We are changing the value of variable baz to reference a new, different object. Thus, obj1 is changed, obj2 is not and the following is logged:

Object {changed: true}
Object {changed: false}

Leave a comment below and follow me on twitter: @QuintonAiken.