Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Side effects». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Side effect (побічний ефект) - це будь-яка дія функції, яка впливає на зовнішній стан або залежить від нього, окрім обчислення значення, що повертається.** Запис у глобальну змінну, `console.log`, зміна DOM, HTTP-запит, читання `Date.now()` чи `Math.random()` - усе це побічні ефекти. Функції з ними називають нечистими (impure), бо вони змінюють світ поза собою й роблять поведінку програми менш передбачуваною. ```javascript let count = 0; function increment() { count++; // changes an outer variable: a side effect } ``` **Ключове:** повністю позбутися побічних ефектів неможливо, інакше програма не взаємодіяла б із зовнішнім світом; мета - ізолювати їх і тримати під контролем.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Side effect (побічний ефект) - це будь-яка дія функції, яка змінює стан поза межами самої функції або залежить від зовнішнього стану, а не просто обчислює результат зі своїх аргументів.** Саме побічні ефекти роблять код складнішим для тестування та передбачення, тому їх намагаються зібрати в окремому, чітко окресленому шарі програми. ## Теорія ### TL;DR - Побічний ефект - це будь-який вплив функції на зовнішнє оточення або залежність від нього поза поверненим значенням. - Класичні приклади: `console.log`, `alert`, зміна DOM, `fetch`, запис у глобальну змінну, робота з файлами. - Залежність від зовнішнього стану теж вважається ефектом: `Math.random()`, `Date.now()`, читання глобальної змінної. - Функція, яка залежить лише від аргументів і нічого навколо не чіпає, називається чистою (pure). - Чистий код легше тестувати, передбачати й безпечніше виконувати паралельно. - Повністю прибрати ефекти неможливо: без них немає UI, мережі та сховища. Мета - ізолювати та контролювати їх. ### Швидкий приклад ```javascript let count = 0; // impure: the function changes an outer variable function increment() { count++; } // pure: the result depends only on the arguments function add(a, b) { return a + b; } increment(); // count is now 1, the outside world changed add(2, 3); // always 5, nothing around it changed ``` ### Що саме вважають побічним ефектом Побічний ефект - це будь-яка зміна поза самою функцією: глобальні змінні, вивід у консоль, запит до сервера, зміна DOM, робота з файлами тощо. Дзеркальний випадок теж рахується: якщо функція читає зовнішній стан, її результат уже не визначається тільки аргументами. | Приклад | Що робить | | --- | --- | | `console.log('Hello')` | Змінює консоль, тобто зовнішнє оточення | | `alert('Hi!')` | Взаємодіє з користувачем | | `document.body.style.color = 'red'` | Змінює DOM | | `fetch('/api')` | Виконує HTTP-запит | | `Math.random()` | Залежить від зовнішнього стану (генератор випадкових чисел) | | `Date.now()` | Залежить від поточного часу | | Зміна глобальної змінної | Змінює стан програми поза функцією | ### Нечиста функція проти чистої Функція з побічним ефектом не лише рахує, а й змінює стан програми: ```javascript let count = 0; function increment() { count++; // changes an outer variable } ``` Функція без побічних ефектів працює тільки зі своїми аргументами і нічого навколо не торкається: ```javascript function add(a, b) { return a + b; } ``` Той самий контраст видно на роботі з масивами: мутація вхідних даних - це ефект, а повернення нової копії - ні. ```javascript // impure: mutates the caller's array function addItem(list, item) { list.push(item); return list; } // pure: returns a new array, the input stays untouched function addItemPure(list, item) { return [...list, item]; } ``` ### Чому це важливо і як це контролювати Код без побічних ефектів легше тестувати (не потрібні моки зовнішнього світу), його результат простіше передбачити, і він безпечніший для паралельного виконання та кешування. Але частина ефектів неминуча: без них програма не спілкувалася б із користувачем, сервером чи файлом. Тому на практиці роблять так: - обчислення тримають у чистих функціях, а ефекти виносять на край програми (обробники подій, шар запитів до `api.example.com`, запис у сховище); - зовнішні залежності передають аргументом, а не беруть із глобальної області, наприклад `function greet(now) { ... }` замість виклику `Date.now()` всередині; - замість мутації вхідних об'єктів повертають нові значення; - у тестах підмінюють саме цей тонкий шар ефектів, а решту коду перевіряють напряму. | Ознака | Side effect | | --- | --- | | Змінює зовнішні дані | Так | | Залежить від зовнішнього стану | Так | | Повертає різні результати на однаковому вводі | Можливо | | Приклад | `console.log`, `fetch`, операції з DOM | | Без побічних ефектів | Чиста функція | Одним реченням: side effect - це будь-який зовнішній вплив функції (зміна оточення або залежність від нього), не пов'язаний напряму з її поверненим результатом. ### Типові помилки - Вважати ефектом лише запис і не помічати читання: `Math.random()` та `Date.now()` роблять функцію нечистою, хоча нічого не змінюють. - Думати, що чистота - це заборона ефектів. Заборонити їх не можна, можна лише винести їх з ядра логіки. - Мутувати переданий об'єкт чи масив і вважати це «просто оптимізацією»: виклик-власник отримує змінені дані й ловить важкі баги. - Ховати запит до мережі чи запис у сховище всередині функції з невинною назвою на кшталт `getUser()`, через що її неможливо викликати в тесті. - Плутати побічний ефект із поверненням значення: `return` - це не ефект, ефект - це все, що функція робить додатково.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.