Чисті функції та побічні ефекти в JavaScript
Що таке чиста функція?
Чиста функція — це функція, яка:
- За однакових вхідних даних завжди повертає однаковий вихід
- Не має побічних ефектів — не модифікує нічого поза своїм обсягом
Приклади чистих функцій
javascript
// ✅ Чиста — однаковий вхід завжди дає однаковий вихід
function add(a, b) {
return a + b;
}
// ✅ Чиста — немає зовнішніх залежностей, немає мутацій
function formatName(first, last) {
return `${first} ${last}`;
}
// ✅ Чиста — створює новий масив, не модифікує оригінал
function double(numbers) {
return numbers.map(n => n * 2);
}Приклади нечистих функцій
javascript
// ❌ Нечиста — залежить від зовнішнього стану
let discount = 0.1;
function getPrice(price) {
return price * (1 - discount); // Результат змінюється, якщо змінюється знижка
}
// ❌ Нечиста — модифікує зовнішній стан (побічний ефект)
let total = 0;
function addToTotal(amount) {
total += amount; // Мутує зовнішню змінну
return total;
}
// ❌ Нечиста — випадковий вихід
function getRandomId() {
return Math.random();
}
// ❌ Нечиста — мутує вхідні дані
function sortArray(arr) {
return arr.sort(); // Модифікує оригінальний масив!
}Що таке побічні ефекти?
Побічний ефект — це будь-яка операція, яка модифікує стан поза обсягом функції:
| Побічний ефект | Приклад |
|---|---|
| Модифікація глобальної змінної | counter++ |
| Мутація вхідних аргументів | array.push(item) |
| Маніпуляція з DOM | document.getElementById() |
| Виклики API | fetch(), XMLHttpRequest |
| Вивід у консоль | console.log() |
| Запис у файли | fs.writeFile() |
| Встановлення таймерів | setTimeout() |
| Модифікація localStorage | localStorage.setItem() |
Як зробити функції чистими
javascript
// ❌ Нечиста — мутує вхідні дані
function addItem(cart, item) {
cart.push(item);
return cart;
}
// ✅ Чиста — повертає новий масив
function addItem(cart, item) {
return [...cart, item];
}
// ❌ Нечиста — мутує об'єкт
function updateAge(user, age) {
user.age = age;
return user;
}
// ✅ Чиста — повертає новий об'єкт
function updateAge(user, age) {
return { ...user, age };
}Чому важливі чисті функції
| Перевага | Опис |
|---|---|
| Передбачувані | Один і той же вхід → один і той же вихід, завжди |
| Тестовані | Не потрібно мокати, просто тестуйте вхід/вихід |
| Кешовані | Результати можуть бути мемоізовані |
| Паралелізовані | Немає спільного стану, безпечно для конкурентності |
| Легко налагоджувані | Немає прихованих змін стану, які потрібно відстежувати |
Чисті функції в React
javascript
// ✅ Чистий компонент — однакові пропси дають однаковий рендер
function UserCard({ name, avatar }) {
return (
<div>
<img src={avatar} alt={name} />
<h2>{name}</h2>
</div>
);
}
// Побічні ефекти йдуть у useEffect
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then(setUser); // Побічний ефект ізольовано
}, [userId]);
return <UserCard name={user?.name} avatar={user?.avatar} />;
}Важливо:
Тримайте функції чистими якомога більше. Ізолюйте побічні ефекти в окремі функції або хуки (useEffect в React). Це робить код більш передбачуваним, тестованим і легшим для розуміння. Більшість патернів функціонального програмування базується на чистих функціях.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.