Immutable/mutable data
Definitions
| Term | Meaning | Essence |
|---|---|---|
| Mutable | changeable | an object that can be changed after creation |
| Immutable | unchangeable | data that cannot be changed: only new data can be created |
Example: mutable data
Objects and arrays in JavaScript are mutable structures.
const user = { name: 'Oleh' };
user.name = 'Maria'; // we change the object
console.log(user); // { name: 'Maria' }Even though the variable
useris declared withconst, its contents (the object) can be changed, becauseconstonly forbids changing the reference itself, not the data it points to.
Example with an array:
const numbers = [1, 2, 3];
numbers.push(4);
console.log(numbers); // [1, 2, 3, 4]Arrays are mutable, because we can add, remove and change elements.
Example: immutable data
Primitives in JavaScript are immutable.
These are:
string, number, boolean, null, undefined, symbol, bigint.
Example:
let a = 'Hello';
a[0] = 'J'; // an attempt to change the string
console.log(a); // "Hello" unchangedStrings are immutable. "Changing" one creates a new string.
Example with numbers:
let x = 5;
let y = x;
y = y + 1;
console.log(x); // 5
console.log(y); // 6Numbers are also immutable: you cannot "change" them, you can only create a new value.
How this works in memory
| Data type | Mutability | Where it is stored | Behavior |
|---|---|---|---|
Primitive (string, number, boolean...) | Immutable | Stack | "Changing" it creates a new value |
| Object, array, function | Mutable | Heap | Changes by reference |
Visually:
let name = 'Ol';
name = name + 'eh';STACK:
┌─────────────────┐
│ name = "Ol" │ ← the old string
│ name = "Oleh" │ ← the new string (created anew)
└─────────────────┘The string
"Ol"does not change, a new one,"Oleh", is created.
Why this matters
1. Behavior on copying
const user1 = { name: 'Oleh' };
const user2 = user1;
user2.name = 'Maria';
console.log(user1.name); // "Maria" ← both changed (mutable)2. In reactive frameworks (React, Redux, Vue, and so on)
Immutability is a key principle:
- It lets you track state changes (by comparing references)
- It makes undo/redo easier
- It makes the code more predictable
Example (the React approach):
// bad (mutable)
state.user.age++;
// good (immutable)
setState({ ...state, user: { ...state.user, age: state.user.age + 1 } });How to make an object immutable manually
const user = Object.freeze({
name: 'Oleh',
age: 25
});
user.age = 30; // this will not work
console.log(user.age); // 25
Object.freeze()makes an object immutable (at the top level). For nested properties you need to "deep freeze" it.
Deep freeze
function deepFreeze(obj) {
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object' && obj[key] !== null) {
deepFreeze(obj[key]);
}
});
return Object.freeze(obj);
}
const data = deepFreeze({
user: { name: 'Oleh', skills: ['JS'] }
});
data.user.name = 'Maria'; // this will not changeSummary
| Category | Examples | Mutability | Behavior |
|---|---|---|---|
| Immutable | string, number, boolean, null, undefined, symbol, bigint | cannot be changed | a new copy is created |
| Mutable | object, array, function, Map, Set | can be changed | changed "in place" |
In short
- Immutable - cannot be changed (only a new value can be created)
- Mutable - can be changed "in place"
- Primitives are immutable, objects and arrays are mutable
- Immutability makes code more reliable, especially in React/Redux
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.