JavaScript Mutable vs Immutable
Learn what a mutable and immutable are, their specificity to JavaScript, immutable vs mutable, the stack and heap data structures, JavaScript primitive types vs reference types, and how variables are stored in JavaScript.
Table of Contents 📖
- Primitive Types and Reference Types
- Primitive Types and Reference Types Storage
- What is a Mutable?
- What is an Immutable?
Primitive Types and Reference Types
To understand mutable vs immutable, we need to first understand the two variable types in JavaScript, primitive and reference, and how they are stored. Primitive types are types that are static in size, not an object, and don't have properties or methods. There are seven primitive types in JavaScript.
- string
- number
- boolean
- undefined
- null
- bigint
- symbol
On the other hand, reference types are dynamic in size, are objects, and have properties and methods. There are three reference types in JavaScript.
- object
- array
- function
Primitive Types and Reference Types Storage
Primitive types are stored in a data structure known as a stack. The stack contains static data, or data whose size is the known at compile time. This works well because primitive types are immutable. On the other hand, JavaScript stores reference types in a heap data structure. In the heap, memory is allocated as needed. This works well because reference types are mutable. However, the reference to the object, array, or function is stored on the stack.
What is a Mutable?
A mutable is a type of variable that can be changed without creating a new value. In JavaScript, reference types are mutable (objects, arrays, and functions). For a demonstration, lets create an array and an object.
const myObj = { name: "WittCode" } const myArray = [0, 1, 2];
console.log(myObj); // {name: 'WittCode'} console.log(myArray); // (3) [0, 1, 2]
Now, lets create copies of each, update them, and then print the original and copies.
const myObj2 = myObj; const myArray2 = myArray;
myObj2.soccer = "fun"; myArray2.push(3);
console.log(myObj); // {name: 'WittCode', soccer: 'fun'} console.log(myObj2); // {name: 'WittCode', soccer: 'fun'}
console.log(myArray); // (4) [0, 1, 2, 3] console.log(myArray2); // (4) [0, 1, 2, 3]
Here, updating the copy also updates the original. This is because assigning the original object and array to the copy creates a reference to the original rather than creating a new object. In other words, the new object and array point back to the original object and array. Therefore, objects and arrays are mutable as their properties and elements can be changed without reassigning a new value.
What is an Immutable?
An immutable is the opposite of a mutable, it is a value that cannot be changed once it is created. Rather, it is reassigned. Unlike we saw with a mutable, modifying the copy of an immutable does not modify the original. In JavaScript, primitive types are immutable. For example, lets say we have the following primitive type variables created.
let myNum = 27; let myString = "Hi how are you";
Now, lets create copies of these primitive types and then update the copies.
let myNum2 = myNum; let myString2 = myString;
myNum2 = myNum2 - 5; myString2 = myString2 += " doing";
console.log(myNum); // 27 console.log(myNum2); // 22
console.log(myString); // Hi how are you console.log(myString2); // Hi how are you doing
When we created a copy of the primitive type variables, a new variable was created entirely. This is clear as when we assigned myNum2 to myNum and myString2 to myString and then updated both, myNum and myString both kept their original values.