Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Почему функция является чистой?
Чистая функция (pure function) — это функция, которая:
- При одинаковых входных параметрах всегда возвращает одинаковый результат
- Не имеет побочных эффектов (не меняет внешнее состояние)
Чистоту функции определяют две основные характеристики.
Характеристика 1: Детерминированность
Для одного и того же входа всегда выходит один и тот же выход:
// ЧИСТАЯ функция
function add(a, b) {
return a + b;
}
add(2, 3); // 5
add(2, 3); // 5
add(2, 3); // 5 (всегда одинаково)
Нечистая функция:
let counter = 0;
function increment(num) {
counter++; // Зависит от внешней переменной
return num + counter;
}
increment(5); // 6 (counter был 0)
increment(5); // 7 (counter теперь 1)
increment(5); // 8 (counter теперь 2)
// Один и тот же вход дал разные выходы!
Характеристика 2: Отсутствие побочных эффектов
Чистая функция не меняет ничего вне её области видимости:
// ЧИСТАЯ функция
function multiply(a, b) {
return a * b; // Только вычисляет и возвращает
}
// НЕЧИСТАЯ функция
let result;
function multiplyAndStore(a, b) {
result = a * b; // Меняет внешнюю переменную (побочный эффект)
return result;
}
Примеры побочных эффектов
// 1. Изменение внешних переменных
let globalData = { count: 0 };
function incrementCount() {
globalData.count++; // ПОБОЧНЫЙ ЭФФЕКТ
return globalData.count;
}
// 2. Запросы к API
function fetchUser(id) {
return fetch(`/api/users/${id}`) // ПОБОЧНЫЙ ЭФФЕКТ
.then(r => r.json());
}
// 3. Изменение DOM
function renderMessage(msg) {
document.getElementById('output').innerHTML = msg; // ПОБОЧНЫЙ ЭФФЕКТ
}
// 4. Вывод в консоль
function processData(data) {
console.log(data); // ПОБОЧНЫЙ ЭФФЕКТ
return data * 2;
}
// 5. Случайные числа
function getRandomId() {
return Math.random(); // Непредсказуемо, не чистая!
}
Почему чистые функции важны?
1. Предсказуемость и тестируемость
// Чистая функция легко тестировать
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}
// Тест:
const items = [
{ name: 'Book', price: 10 },
{ name: 'Pen', price: 2 },
];
const total = calculateTotal(items);
assert.equal(total, 12); // Всегда 12
2. Переиспользование кода
Чистую функцию можно вызвать когда угодно, где угодно, и результат будет один и тот же:
function getDiscount(price, percentOff) {
return price * (1 - percentOff / 100);
}
// Используем где угодно — результат всегда предсказуем
const cartTotal = getDiscount(100, 10); // 90
const orderTotal = getDiscount(100, 10); // 90
3. Оптимизация и кэширование
// Можно кэшировать результаты чистой функции
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
const cache = {};
function memoizedFib(n) {
if (cache[n] !== undefined) return cache[n];
const result = fibonacci(n);
cache[n] = result;
return result;
}
4. Паралелизм и конкурентность
Чистые функции можно безопасно выполнять параллельно:
function processItem(item) {
return item.value * 2; // Чистая
}
const items = [1, 2, 3, 4, 5];
const processed = items.map(processItem); // Безопасно параллельно
React и чистые функции
В React компоненты должны быть чистыми функциями по отношению к своим props:
// ЧИСТЫЙ компонент (Strict Mode проверяет это)
function UserCard({ user }) {
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
// Одинаковые props = одинаковый результат
const user = { name: 'John', email: 'john@example.com' };
const rendered1 = <UserCard user={user} />;
const rendered2 = <UserCard user={user} />;
// Оба вывода одинаковые
// НЕЧИСТЫЙ компонент
let renderCount = 0;
function ImpureCounter() {
renderCount++; // Побочный эффект
return <div>{renderCount}</div>; // Разные выходы для одних props
}
Как функция становится нечистой?
const userData = { name: 'John' };
// Начинается как чистая
function greet(name) {
return `Hello, ${name}`;
}
greet('John'); // 'Hello, John'
// Становится нечистой, если:
// 1. Зависит от внешнего состояния
function greetUser(name) {
return `Hello, ${name}! You are ${userData.age} years old`;
// Теперь зависит от userData
}
// 2. Меняет внешнее состояние
function addUser(name) {
userData.friends.push(name); // Побочный эффект
return userData;
}
// 3. Имеет случайность
function getGreeting(name) {
const greeting = Math.random() > 0.5 ? 'Hello' : 'Hi';
return `${greeting}, ${name}`;
}
Чистые и нечистые версии
// НЕЧИСТАЯ: Изменяет исходный массив
function addItem(items, newItem) {
items.push(newItem); // ПОБОЧНЫЙ ЭФФЕКТ
return items;
}
// ЧИСТАЯ: Создаёт новый массив
function addItem(items, newItem) {
return [...items, newItem]; // Новый массив
}
const list = [1, 2, 3];
const newList = addItem(list, 4);
console.log(list); // [1, 2, 3] (не изменился)
console.log(newList); // [1, 2, 3, 4] (новый массив)
Best Practices
- Пиши чистые функции по умолчанию
- Избегай изменения параметров:
// ПЛОХО function updateUser(user) { user.name = 'New Name'; } // ХОРОШО function updateUser(user) { return { ...user, name: 'New Name' }; } - Передавай зависимости как параметры
- Возвращай новые объекты вместо мутирования
- Используй чистые функции в React компонентах
Вывод
Функция является чистой, когда она детерминирована (одинаковый вход = одинаковый выход) и не имеет побочных эффектов. Чистые функции — это основа предсказуемого, тестируемого и масштабируемого кода в JavaScript и особенно в React.