The concept of mutability in JavaScript is one of the most confusing especially for beginners. Let us begin by defining mutability. According to the Cambridge dictionary, mutability is the ability to change or be likely to change. In programming, we can refer to mutability as the concept of methods changing or not changing existing data.
Although they are not part of the scope of this topic, it is hard not to talk about reference and primitive data types. So briefly let us get that out of the way.
When we talk about primitives, we are talking of data types that can not be changed, that is, they are immutable; these include boolean
, null
, undefined
, number
, and string
.
Reference types are the ones that can be changed and these include objects
. An array is also a kind of object.
We're going to use strings and arrays to demonstrate the concept of mutability. Although both strings and arrays have indices, and lengths and share common methods like concat
, indexOf
, and slice
, they differ so much in mutability.
Strings are immutable
Methods that manipulate strings never modify the existing string but rather create a new one. Immutability does not happen to strings only but to also other data types that are primitive. These include undefined, null, number, symbol, boolean, and null but our focus is going to be on strings.
First, let's create a variable that stores text and change it to capital letters using the toUpperCase()
method.
let name = "Sarah Seremba";
let makeNameUpperCase = name.toUpperCase();
console.log(makeNameUpperCase); // SARAH SEREMBA
The toUpperCase()
method does not change the original string but instead returns a new string of characters in capital letters.
Another example to help us better understand the immutability of strings is the use of slice()
method. The slice()
method extracts, as in it removes a part of the string and returns that extracted part as a new string.
Let's create a variable to store the full name.
let name = "Sarah Seremba";
Now, let's use the slice method to extract "Sarah" and return the text as a new string.
const pickSarah = name.slice(0, 5);
console.log(pickSarah) // Sarah
console.log(name) // prints Sarah Seremba, so it was not mutated.
We have established that strings are immutable, it is impossible to change them; how about arrays, are they immutable too? You guessed right, they are not.
Arrays are mutable
Unlike strings which are of primitive type, arrays are reference in nature. Arrays can be mutated, or changed by adding elements to them, removing elements from them, etc.
Adding to the array
To add an element to an array, we use the methods unshift()
and push()
.
The unshift()
method adds one or more elements at the beginning of the array and returns the new length of the array. Let's create an array of friends
let friends = ["React", "Vue", "Svelte"];
we can now mutate the size of the array of friends by adding another friend or friends to it.
let friends = ["React", "Vue", "Svelte"];
console.log(friends.unshift("Express", "Next")); // 5
console.log(friends) // [ 'Express', 'Next', 'React', 'Vue', 'Svelte' ]
For the push()
method, it pushes the elements out the window! Lol, no I am kidding! The push()
method adds one or more elements at the end of the array and returns the new length of the array.
Remember that our array is now like this [ 'Express', 'Next', 'React', 'Vue', 'Svelte' ]
. So let's add two more friends at the end of our friends
array.
console.log(friends.push("Nuxt", "Angular")) // 7
console.log(friends) // ['Express', 'Next','React', 'Vue','Svelte', 'Nuxt', 'Angular']
Removing from an array
An array can also be mutated by removing one or more elements from it. To remove an element from the array, we use the shift()
and pop()
methods.
The shift() array method removes the first element from an array and returns that removed element; This will of course change the size of the array. Using our friends
array let us use shift()
to remove the first element. Currently, our array is like this ['Express', 'Next','React', 'Vue','Svelte', 'Nuxt', 'Angular']
let removeFirst = friends.shift();
console.log(removeFirst); // Express
console.log(friends) // [ 'Next', 'React', 'Vue', 'Svelte', 'Nuxt', 'Angular' ]
The pop()
method removes the last element from the array and returns the removed element. This too changes the size of the array. Continuing with our friends
array, let us see how pop()
affects the array. Currently, our array is like this [ 'Next', 'React', 'Vue', 'Svelte', 'Nuxt', 'Angular' ]
let removeLast = friends.pop();
console.log(removeLast); // Angular
console.log(friends) // [ 'Next', 'React', 'Vue', 'Svelte', 'Nuxt' ]
Conclusion
As we end this topic, remember that mutability refers to the concept of modifying existing data. Primitives like boolean, null, undefined, number, and string are immutable, that is cannot be directly changed. References like arrays and objects are mutable, that is, they can be changed.