Mutation means to change something.
Consider the following example:
In the example given above,
we are mutating both
the fruits
array by changing
the value of an element
and
the user
object by changing
the value of a property.
Mutating objects and arrays
can lead to unwanted outputs.
Let's say we have an array fruits
that contains names of some fruits.
We want to temporarily sort the array
and
display the sorted array.
Then we want to display the array
in its original order.
In the example given above:
-
We are displaying the fruits
array
after sorting it using the printSortedList
function.
We pass fruits
as the argument for
the list
parameter in the printSortedList
function.
-
Inside the printSortedList
function,
we use list.sort()
to sort the array
and
then display it using console.log()
.
Here, we are mutating the list
array
when we use list.sort()
.
Since list
is a reference to
the fruits
array,
we are mutating the fruits
array as well.
-
When we display the fruits
array after
printSortedList(fruits)
,
we get the sorted array,
even though our intention is to show
the list in its original order.
To prevent such unwanted outputs,
it is a good practice to avoid using
methods that mutate arrays and objects.
Methods such as sort
, splice
, pop
, and push
mutates the array it is invoked on.
Similarly, Object.assign()
mutates the object
passed as the first argument to it.
There are ways we can use these methods
or achieve the same thing
that these methods achieve
without mutating the original array or object.
Let's take sorting an array for example:
In the example given above,
-
[...list]
creates a copy of the list
array.
-
[...list].sort()
sorts the copy of
the list
array that was created.
This way the original array - list
remains unchanged,
therefore fruits
also remains unchanged.
Similarly, there is a way to add
a new property to an object,
apart from using Object.assign()
.
In the example given above,
we have two functions:
-
addDefaultPropsUsingAssign
-
adds the role
and password
properties to the person
parameter
using Object.assign()
.
-
addDefaultPropsUsingSpread
-
creates a new object,
that contains properties
of the person
parameter
as well as the role
and password
properties using ...
operator.
Both functions perform the same operation,
i.e., add the role
and password
properties
to an object.
addDefaultPropsUsingAssign
mutates the object that is
passed as argument to it.
So addDefaultPropsUsingAssign(user1)
mutates user1
itself.
addDefaultPropsUsingSpread
creates another object
that contains the properties
of the object passed as argument
and
adds the new properties.
Hence, when we perform
const updatedUser2 = addDefaultPropsUsingSpread(user2)
,
user2
remains unchanged
and
we assign the new object with
the added properties in updatedUser2
.
Mutation of objects and arrays should be avoided at all cost.
Only if we come across a situation where
we absolutely have no other choice,
should we mutate an object or an array.