Skip to main content

Імутабельність у функціях

Імутабельність (immutability) - це принцип, за яким дані не змінюються після створення, а у функціях він означає заборону мутувати вхідні аргументи: замість зміни на місці функція повертає нове значення. Це один із ключових принципів чистих і передбачуваних функцій: якщо функція змінює переданий масив або об'єкт, вона впливає на зовнішній стан і стає нечистою.

Теорія

TL;DR

  • Імутабельність означає, що дані не змінюються після створення.
  • У функціях це правило звучить так: не мутуй аргументи, повертай нову структуру.
  • Мутація аргументів це побічний ефект: вихідні дані виклику-власника змінюються непомітно.
  • Імутабельні інструменти: map, filter, concat, spread для масивів і { ...obj } для об'єктів.
  • Мутабельні операції, яких уникають у чистих функціях: push, pop, splice, sort, reverse, пряме присвоєння полю.
  • Рядки в JavaScript імутабельні завжди, змінити їх на місці неможливо.

Швидкий приклад

javascript
// mutable: changes the caller's array function addItemMutable(arr, item) { arr.push(item); return arr; } // immutable: returns a new array function addItem(arr, item) { return [...arr, item]; } const numbers = [1, 2, 3]; console.log(addItem(numbers, 4)); // [1, 2, 3, 4] console.log(numbers); // [1, 2, 3], the source is intact

Мутація проти нової копії

Мутабельний підхід змінює те, що йому передали:

javascript
function addItem(arr, item) { arr.push(item); // changes the original array return arr; } const numbers = [1, 2, 3]; const result = addItem(numbers, 4); console.log(numbers); // [1, 2, 3, 4], the source data changed

Імутабельний варіант створює новий масив і лишає вхідні дані такими, якими вони були:

javascript
function addItem(arr, item) { return [...arr, item]; // creates a new array } const numbers = [1, 2, 3]; const result = addItem(numbers, 4); console.log(numbers); // [1, 2, 3], the source data is preserved console.log(result); // [1, 2, 3, 4]

Функція не змінила вхідні дані, а повернула нову копію, і це і є імутабельність.

Імутабельні та мутабельні операції

Тип данихІмутабельний спосіб
Масивmap(), filter(), concat(), spread ([...arr])
Об'єкт{ ...obj, key: newValue }
РядокЗавжди імутабельний, у JavaScript рядок змінити не можна
Тип данихМутабельна операція
------
Масивpush(), pop(), splice(), sort(), reverse()
Об'єктПряме присвоєння obj.key = value

Якщо мутабельна операція все ж потрібна, спершу роблять копію: [...arr].sort() замість arr.sort().

Навіщо потрібна імутабельність

  • Робить функції чистими та передбачуваними.
  • Спрощує налагодження й тестування: вхідні дані після виклику лишаються тими самими.
  • Прибирає побічні ефекти, бо ніщо поза функцією не змінюється.
  • Дозволяє безпечно розпаралелювати операції, немає гонки за спільні дані.
  • Полегшує порівняння станів і відкат, наприклад у React і Redux, де нове посилання означає «дані змінилися».
ВластивістьІмутабельна функція
Змінює вхідні даніНі
Створює нові структуриТак
Побічні ефектиНі
ПередбачуваністьВисока
Прикладиmap, filter, reduce

Типові помилки

  • Використовувати sort() або reverse() на переданому масиві: обидва методи змінюють його на місці.
  • Вважати spread глибоким копіюванням: { ...obj } копіює лише верхній рівень, вкладені об'єкти лишаються спільними.
  • Мутувати аргумент і повертати його ж, вважаючи, що «зовні ніхто не помітить»: виклик-власник тримає те саме посилання.
  • Плутати const з імутабельністю: const забороняє перепризначення змінної, але не заважає змінювати вміст масиву чи об'єкта.
  • Створювати копію на кожен крок у гарячому циклі, не вимірявши вартість: в окремих випадках потрібна локальна мутація всередині функції над власною копією даних.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.