Reference vs Primitive Values Types in Mutable and Immutable Javascript
Reference vs Primitive Values Types in Mutable and Immutable Javascript

In this video you will learn the difference between reference vs primitive values types in Javascript. Also I will show you the difference between mutable and immutable data in javascript and how to use immutability to make your code less error prone. It's really easy to change the value of your variable by accident with mutable data this is why we need a better approach using immutability.

The first and most important point is what does it mean - immutable data. It's data that cannot be reassigned. This means that when you have a variable and modify it's value, you get a new variable and never ever change the old one.

On the opposite side mutable data means that we can change the variable itself.

And you might us what the point of have variables that you can't change.

So let's check on the example. For example a have a variable

var a = 'foo'
var b

b = a
b = 'bar'
console.log(a, b)

As you can see in browser, everything is working at expected. We created a variable, reassined he value of b and everything is working.

Let's try another example

var a = {foo: 'foo'}
var b

b = a
b.foo = 'bar'
console.log(a, b)

As you can see in this case everything is not like we expected. We wanted to change just a value of b but we also change a.

Why is it happening?

In javascript you can assign data by value and by reference. As you saw our first example was assigning by value. So we simple reassined the value and everything is working

In our example with object we got reference assigning. This means that we have just a reference to the same object in memory from this two variables.

It's super important to remember that all primitive values like Strings, Numbers, Booleans and so on are assigned by value and Arrays and Objects by reference.

And this assign by value actually means that they are immutable and assign by reference means that they are mutable.

So basically every time when we assign a string for example we create a copy of the value and if it's an object we are mutating the same object again and again.

So now it should a clear for you the difference between mutable and immutable data. Let's have a look on a huge pitfall that we have when the data is mutable.

Let's say that we have a baseConfig with some properties

var baseConfig = {apiUrl: 'http://someapi.com', port: 4000}

Then we want to create a function which creates extended config for us

function createExtendedConfig (config) {
  config.host = 'http://google.com'
  return config
}

var extendedConfig = createExtendedConfig(baseConfig)

Everything looks fine. We have our baseConfig. We created a function which gets a config inside, modifies it and returns so we can assign it to new property. But it's not fine at all. It's a huge problem and infinite place to get bugs.

The problem is here that after we run this code we don't only create extendedConfig. We modified initial baseConfig object without knowing or wanting this behaivour. Why is it bad? Just imagine that your initial data is in one place of you code and you function where you pass this data is in another place. You object was magically modified somewhere and it's really difficult to find the place where.

Why this happens? As we already know because objects and arrays are working by reference in javascript and not by value. This means that when you pass string in function as a parameter you will pass just it's value. So it's completely safe to modify it. But objects and array are not passed by value. They are always referenced. This means that your modifications inside a function will change initial object that you've pass inside.

This is not good behaivour at all because it's too difficult to debug it lately.

What solution do we have to this problem? First of all you should always think when you modify something.

To fix this example we can create new object inside function before returning it.

function createExtendedConfig (config) {
  return Object.assign({}, config, {host: 'http://google.com'})
}

var extendedConfig = createExtendedConfig(baseConfig)

Object assign is the easiest solution to this problem. Here we just create new object and modify it instead of modifying old one by reference. Almost always with plain javascript I'm using this variant.

Some people saying that immutable data is not fast enough because we always create copies of elements and not reusing all elements. And it's a valid point. Yes immutable data are slower than mutable. However performance impact is not that huge in comparison with DOM rendering, database quering and other long stuff. There are lost of projects which use immutable data and don't have any problems with performance.

This is the main problem on mutable data. You should always think and remember when you mutate data and when not. It's not comfortable. The obvious solution to me is to use only functions that doesn't mutate data. Functions like filter, map, reduce, object.assign and tons of other methods always return new data and never mutate old data. But for example push, pop, splice, sort are mutable.

Also there are libraries which are trying to solve this problems by building new abstractions and adding complexity. It started with immutable.js and now there is immer.js. I can't recommend this things.

I like to keep it simple. So I can recommend you 2 libraries.

First is Lodash. This is the most popular library with hundreds of useful functions that don't exist in javascript. You can just use functions that don't mutate data from this library and you are good to go. No complexity and no magic.

The second library is a big advanced. It's called Ramda and has also hundreds of useful function but they are all in functional way and they are all immutable. So using Ramda you are just always sure that you won't mutate anything ever.

So this are the most important things that you need to know about immutability in javascript.

If you are interested in learning programming don't forget to check my courses in the description below, especially Ramda and Lodash courses as they are directly related to our topic.

📚 Source code of what we've done