Why use immutable vs mutable code in JavaScript?


By: Andres Castillo Ormaechea

I am creating this post because I was using a simple for (element in array) {}` loop that drove me into unexpected behaviour and I went into a rabbit hole for two (2) days. So I thought I should at least dedicate a small post to explain how to avoid this from the very beginning.

But first. What the heck is mutable and immutable code?

The word mutable refers to "liable to change" or simply put "changeable" code. When talking about mutable code we are referring specifically to mutable data structures like objects { apple: "fruit"} , arrays ["apple", "banana"] etc. and there possibility of changing its form or structure. An example to illustrate mutable and immutable code:

Let's say we have a collection of food with their category. We noticed there is a mistake so we want to update the object in order to be correct. Let's do this first with mutability:

Now, lets do this with immutability:

Can you notice the difference between the two? We can see here that instead of changing an object property we decided to create a whole new object that will incorporate the changes we wanted to make.

Ok, I see... But what is the point? How can this benefit me?

Using immutable code can benefit you in the following ways:

  • Predictability.
  • Change tracking / history.
  • Avoiding a reference clash.
  • Avoiding an unexpected behaviour in general.

Let's see some examples. In JavaScript there are two types of variable assignments.

  • Assign by value.
  • Assign by reference.

How assign by value in JavaScript works.

How assign by reference in JavaScript works.

What happens here is that in JavaScript Arrays and Objects work with references, this means that the assignment is an address in memory that holds the value so creating another variable like we did with var exoticFruits = fruits; will just hold the same address as fruits hence returning the same value.

Primitive data types (String, Number, Boolean, undefined, null, Symbol) work with assignments by value so they will directly store the value that was assigned instead of a reference (address in memory).

Why is this important for the immutable code concept?

When we work with asynchronous code it adds a layer of concepts to keep in mind as there is no speicific sequence of orders in which instructions will occur. This can lead to a reference clash for example in which the variable element of a for (element in array) {}` loop can retain a reference of the previous loop. Add to that a layer of complexity by implementing a nested for loop with asynchronous code. Lot's of things to keep in mind while debugging code no?

I was not able to replicate exactly the reference clash issue I encountered but I will share with you two different pieces of code to illustrate the use of mutable and immutable code:

Mutable code

Immutable code

Isn't the immutable approach much easier to read? For some reason I always thought that creating new instances in the process would complicate things and make it much harder to read. But this is not the case. With immutable code I was able to:

  • Avoid unexpected behaviours.
  • Code looks much more cleaner and easier to read.
  • I can check the before and after state of my changes in the object.
  • A more pure functions approach which is easier to debug.

I would encourage the use of functions like .map().filter() and .reduce() in JavaScript since these functions work with the immutable approach.