Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Імутабельність у функціях». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Імутабельність (immutability) - це принцип, за яким дані не змінюються після створення; для функцій це означає, що вони не мутують вхідні аргументи, а повертають нові значення й лишають вихідні дані недоторканими.** Замість `arr.push(item)` функція робить `[...arr, item]`, замість `obj.key = value` повертає `{ ...obj, key: value }`. Функція, яка змінює передані дані, впливає на зовнішній стан, тому стає нечистою і важкою для налагодження. ```javascript function addItem(arr, item) { return [...arr, item]; // creates a new array, the input stays intact } ``` **Ключове:** імутабельна функція не чіпає вхідні дані, а створює нову структуру, і саме це робить її передбачуваною.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Імутабельність (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` забороняє перепризначення змінної, але не заважає змінювати вміст масиву чи об'єкта. - Створювати копію на кожен крок у гарячому циклі, не вимірявши вартість: в окремих випадках потрібна локальна мутація всередині функції над власною копією даних.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.