arrow-rightgithublinkedinscroll-to-topzig-zag

What does immutable mean in Javascript? Explaining by the simple example

Last Updated On

If you're asking this question you probably already know how it's important (whether it's for the job interview or for daily programming routing) to understand immutability. The goal here is to provide you real-world example to help grasp this idea quicker. I also promise that it will be the last time when I use word immutable before I get to the key point.

Use case with string processing

One of the most popular use cases where it's important to understand this idea is string processing.

Real world task (simplified):

Parse a URL and save its relative path to a separate variable to recreate folder structure in Linux and Windows formats later on.

For example, when parsing https://example.com/products/popular/bikes/road-bikes/index.html

  1. One result should be products/popular/bikes/road-bikes (for Linux).
  2. Another result should be products\popular\bikes\road-bikes (for Windows).

Let's walk through the solution:

// 1. The URL itself
const url = "https://example.com/products/popular/bikes/road-bikes/index.html";

// 2. To split URL into parts will use '/' as a separator for paths
const urlParts = url.split('/');

/* 3. The result of the second operation will be the following:
["https:", "", "example.com", "products", "popular", "bikes", "road-bikes", "index.html"];

/* 4. Since we need to extract everything starting from the third element before the last one let's use splice. It accepts 
 1. the index of the starting element you want to extract from
 2. the number of the subsequent element needed to be extracted. 
In our case the starting element will be 3, since 0, 1, 2 will always be "https:", "", "example.com"
The nubmer of subsequent elements can be calculated by subracting four elements 
"https:", "", "example.com", "index.html"
from the the total length: (urlParts.length - 4).
*/
const linuxSubpath = urlParts.splice(3, urlParts.length - 4).join('/');
const windowsSubpath = urlParts.splice(3, urlParts.length - 4).join('\\');

As a result subpath will be equal to:

// linuxSubpath = 'products/popular/bikes/road-bikes';
// windowsSubpath = '';

The question is - what does happen to windowsSubpath if we applied exactly the same method as for linuxSubpath just with different separator?

The actual problem here is in the splice() method. It actually modifies or mutates the original value of urlParts array by removing selected items from it. The urlParts.splice(3, urlParts.length - 4).join('/'); removed 4 items and instead of having:

["https:", "", "example.com", "products", "popular", "bikes", "road-bikes", "index.html"];

started to have this value globally:

["https:", "", "example.com", "index.html"];

From now on, everybody who wants to access urlParts will get modified value instead of original one and it's safe to say, that splice() is a mutable function.

The alternative way to solve this problem is by using slice() function which takes the index of starting element you want to extract from and ending index:

const url = "https://example.com/products/popular/bikes/road-bikes/index.html";
const urlParts = url.split('/');
const linuxSubpath = urlParts.slice(3, urlParts.length - 2).join('/');
const windowsSubpath = urlParts.slice(3, urlParts.length - 2).join('\\');

The result will be:

// linuxSubpath = 'products/popular/bikes/road-bikes';
// windowsSubpath = 'products\popular\bikes';

In this case, it's reasonable to say that slice() is immutable function, i.e. does not modify or mutate the original value of urlParts.

Disclaimer for perfectionists: It's clear that this problem can be solved in a hundred different ways (including one-line solution), but this approach clearly highlights the main problem of this article.

Conclusion

When working with pure javascript applications and front-end frameworks there is always a case when it's needed to provide only filtered part of some sort of data: filter posts by tags in a blog, display flights during selected rage on airlines portal, etc. The filtered data is condensed version of the original data and it's being created when a new filter or sorting algorithm is applied. As it's pretty obvious, the original data shouldn't be modified. It's important to understand which functions modify the initial data and which don't. Without a proper understanding of this concept your code might be easily broken and even worse, lead to unwanted results which are very difficult to debug.