Immutable Object and Array operations in Javascript

Nitish Phanse
3 min readMar 27, 2018

--

Immutable:

unchanging over time or unable to be changed.

The entire ideology of an immutable operation is what constitutes functional programming in javascript. The basic premise being, any object once modified should not be changed over the course of time. Instead a new object should be used. Developers using React / Redux would have surely come across this concept, by using pure functions to update state.

Objects in javascript are memory references, hence equating two objects results in equating their memory references.

Consider the code below.

const foo = {
firstName: 'John',
secondName: 'Doe'
}const bar = foo;
bar.firstName = 'Jane';
console.log(foo.firstName);
// Outputs Jane

Simple enough. bar points to the memory location of foo, and hence foo gets mutated. If somewhere in your application foo.firstName was dependent on “John”, it would’ve broken without your knowledge. Mutation there by has a side effect of causing unwarranted bugs. The immutable approach, takes input (object or array) and returns a new copy / modified copy of the input, there by creating a new memory location. The side effect of this is garbage collection can really be high if done on very large lists / arrays, which is why highly optimized libraries like ImmutableJS were made to solve this problem.

Although most of the times simple vanilla JS methods are enough to carry out array / object immutable operations.

Base case

For the remaining bit of this article i’m assuming the following type declarations.

type Student = {
name: string,
rollNumber: string,
age: number,
rank: number
}
type Students = Array<student>

All the examples mentioned below are immutable operations on the aforementioned types.

Changing / Adding a key in an object

const student1 = {
name: 'John Doe',
rollNumber: 'Aa123',
age: 25,
rank: 2
}
const student2 = Object.assign({}, student1, {
name: 'Jane Doe',
age: 22
});
or in Es6const student2 = {...student1,
name: 'Jane Doe',
age: 22
};

This creates a shallow copy of the student1 object and modifies only the name and age keys. I have kept this article to a bare minimum to keep the concept lucid. Incase your object has nested objects, then creating shallow copying can be a little tricky as both objects use shared memory references for nested objects. In such a case the nested key can be spread and the same syntax as mentioned above can be used.

Adding an element to the end of array

students.concat([newStudent])

Adding an element to the start of array

newStudent.concat([students])

Deleting an object based on index from array

[...students.slice(0,index), ...students(index + 1)];

Deleting an object from the array based on some property

students.filter((student) => student.rank < 5)

Updating a value of a particular object

students.map((student) => {
if(someProperty !== student.key) return student
return {...student, NEW_OBJECT}
})

You can read more about, Map, Filter, Reduce here

All the methods mentioned above, create a new array / object. The students array is unchanged and every time one of the above methods gets called, it creates a new array.

Hope this was short and sweet.

--

--

Nitish Phanse

Javascript developer. Fiddles around with Node and React. Wants to try scuba diving.