Developing a Good Habit on Making the Original Object Immutable

When I first learned how to code, I was confused about the concept “Variables as pointers”. Oftentimes, I inadvertently changed the original variable after reassigning another different variable, and that’s when the mistakes happened by creating the “side effect”. To avoid such mistakes, 1) it is important to understand the concepts about mutable/immutable objects, 2) we need to develop a good coding habit if we don’t want to change the original object.


  1. Mutable vs. Immutable

When we talk about mutable object, it means that we can change the object’s values after we create it. An immutable object is the opposite: We can not change the values after initiating it. In JavaScript, two major data types that are immutable are numbers and strings.

Let’s consider an example for immutable value:

> var a = 1;
=> undefined
> var b = a;
// assigns b to a
=> undefined
> a += 1;
// reassigns a's value
=> 2
a
=> 2
b
=> 1

Here, the values of numbers are actually not changed(immutable), that is why b’s value is still “1”. Variables hold a reference to the values. What we are changing is pointing the variable to a different value with the `=` operator.

Next, let’s look at another example for mutable value with object:

> var a = 1;
=> undefined
> var obj = { a: a }
=> undefined
> var newObj = obj; // assigns newObj to obj
=> undefined
> obj.a += 2; // updates obj's property "a"
=> 3
> obj
=> { a: 3 }
> newObj
=> { a: 3 }
> a // value of var a will not change
=> 1

From the above example, we can see that objects are mutable: changing a variable’s state also modifies all references to that variable. When we update obj, value of newObj also changes. Both obj and newObj point to the same address in memory.

In contrast, for the immutable data type number, we can not change the internal state of the data, so the value of var a remains unchanged.


2. “Copy” the variable, instead of reassigning

Now that we know simply reassigning an object’s property will change the original object , it is important to have a good discipline. For example, if you want to show changes of an item and want to display both “before” and “after” states to your user, you will still need to keep the original object in order to implement this feature.

In this case, we can use Object.assign in JavaScript to copy the original object, to avoid the changes reflect on it. The other way to make the object immutable is through Object.freeze. The reason I do not recommend to use Object.freeze function is that, it may prevent us from any changes, and it doesn’t have much flexibility.

Below is the example on Object.assign:

> var obj = { a: "foo", b: "bar" }; 
=> undefined
> var copy = Object.assign({}, obj);
=> undefined
> copy
=> { a: 'foo', b: 'bar' }
> copy.a = "hello";
=> 'hello'
> copy;
=> { a: 'hello', b: 'bar' }
> obj;
=> { a: 'foo', b: 'bar' }

In the example above, we first use Object.assign({}, obj) to make a copy and assign it to a variable copy. Next, we make the changes on a property in the copy variable. After changing, we successfully changed the copy object without modifying the original obj object.

If you are dealing with array, an easier function to copy the array is using Array.prototype.slice() .


Sometimes making mistakes is inevitable, but if you keep practicing and exploring the reasons behind the mistakes, they will help you to be a better developer.