Immutable/mutable дані
Визначення
| Термін | Переклад | Суть |
|---|---|---|
| Mutable | змінюваний | об'єкт, який можна змінювати після створення |
| Immutable | незмінюваний | дані, які не можна змінити: можна лише створити нові |
Приклад: змінювані (mutable) дані
Об'єкти і масиви в JavaScript - змінювані структури.
const user = { name: 'Oleh' };
user.name = 'Maria'; // змінюємо об'єкт
console.log(user); // { name: 'Maria' }Хоча змінна
userоголошена черезconst, її вміст (об'єкт) можна змінити, тому щоconstзабороняє змінювати саме посилання, а не дані, на які воно вказує.
Приклад з масивом:
const numbers = [1, 2, 3];
numbers.push(4);
console.log(numbers); // [1, 2, 3, 4]Масиви - mutable, тому що ми можемо додавати, видаляти і змінювати елементи.
Приклад: незмінювані (immutable) дані
Примітиви в JavaScript - незмінювані.
До них належать:
string, number, boolean, null, undefined, symbol, bigint.
Приклад:
let a = 'Hello';
a[0] = 'J'; // спроба змінити рядок
console.log(a); // "Hello" не змінилосяРядки - immutable. При "зміні" створюється новий рядок.
Приклад з числами:
let x = 5;
let y = x;
y = y + 1;
console.log(x); // 5
console.log(y); // 6Числа теж immutable: їх не можна "поміняти", можна лише створити нове значення.
Як це працює в пам'яті
| Тип даних | Змінюваність | Де зберігається | Поведінка |
|---|---|---|---|
Примітив (string, number, boolean...) | Immutable | Stack | При "зміні" створюється нове значення |
| Об'єкт, масив, функція | Mutable | Heap | Змінюється за посиланням |
Візуально:
let name = 'Ol';
name = name + 'eh';STACK:
┌─────────────────┐
│ name = "Ol" │ ← старий рядок
│ name = "Oleh" │ ← новий рядок (створений заново)
└─────────────────┘Рядок
"Ol"не змінюється, створюється новий"Oleh".
Чому це важливо
1. Поведінка при копіюванні
const user1 = { name: 'Oleh' };
const user2 = user1;
user2.name = 'Maria';
console.log(user1.name); // "Maria" ← обидва змінилися (mutable)2. У реактивних фреймворках (React, Redux, Vue тощо)
Іммутабельність - ключовий принцип:
- Дозволяє відстежувати зміни стану (через порівняння посилань)
- Полегшує відкат змін (undo/redo)
- Робить код більш передбачуваним
Приклад (підхід React):
// погано (змінюваний)
state.user.age++;
// добре (іммутабельний)
setState({ ...state, user: { ...state.user, age: state.user.age + 1 } });Як зробити об'єкт незмінюваним вручну
const user = Object.freeze({
name: 'Oleh',
age: 25
});
user.age = 30; // не спрацює
console.log(user.age); // 25
Object.freeze()робить об'єкт immutable (на верхньому рівні). Для вкладених властивостей потрібно "глибоко заморожувати".
Глибока заморозка (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'; // не змінитьсяПідсумок
| Категорія | Приклади | Змінюваність | Поведінка |
|---|---|---|---|
| Immutable (незмінювані) | string, number, boolean, null, undefined, symbol, bigint | не можна змінити | створюється нова копія |
| Mutable (змінювані) | object, array, function, Map, Set | можна змінити | змінюються "на місці" |
Коротко
- Immutable - не можна змінити (тільки створити нове значення)
- Mutable - можна змінити "на місці"
- Примітиви - immutable, об'єкти і масиви - mutable
- Іммутабельність робить код надійнішим, особливо в React/Redux
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.