Ah, immutability. Where to even begin.
Why do we want immutability?
Immutability severely reduces bugs in your code by limiting any outside modifications that you did not intend.
All objects in JavaScript are mutated via reference. Meaning if you do this:
var obj = {
greeting: 'Hello!'
}
function someHelperFunction() {
obj.greeting = 'Hola'
}
someHelperfunction();
console.log(obj.greeting) // Hola
Even though someHelperFunction() doesn't own the obj variable, it can still mutate it's property and it will be reflected anywhere that obj is used.
Immutability is a concept taken from functional programming languages. Instead of mutating the object's value, it uses functions to create a new object, modify that one, and return the resulting new object. Immutable mutations always return a copy of the previous object.
Let's take a functional approach to the above example.
var obj = {
greeting: 'Hello!'
}
var obj2 = obj
function someHelperFunction(object) {
var copy = { ...object }
copy.greeting = 'Hola'
return copy
}
obj = someHelperFunction(obj)
console.log(obj.greeting) // Hola
console.log(obj2.greeting) // Hello!
So this has a lot going on here but you can see we already have gained so many positive things. Let's break it down:
We removed the side effect from someHelperFunction. We turned it into a pure function which owns all of its state (no modifications to global vars). It makes a copy of the inputted object as to not modify the reference (using ES2015 object spread). It modifies the new object, and then returns it.
We can see exactly where obj changed, because we are reassigning its value via that function. In the first example, if it were a bigger codebase, we'd have to search through all of the code trying to find out where our variable is being mutated without us directly assigning it.
Another benefit added here was that we assigned obj2 equal to obj. If we had just mutated obj directly, our obj2 values all would have updated as well. This functional approach eliminated that side effect and now they both have their intended values.
This is just a bonus but pure functions are so easy to test. Given the same input, this function will return the same output every single time.
Anyway, it's late and I'm exhausted but I love talking about this topic so I thought I'd chime in. If this doesn't answer your question or is crazy hard to follow I'll come back in the morning and update it.