← Назад к вопросам

Почему функция является чистой?

1.0 Junior🔥 171 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI21 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Почему функция является чистой?

Чистая функция (pure function) — это функция, которая:

  1. При одинаковых входных параметрах всегда возвращает одинаковый результат
  2. Не имеет побочных эффектов (не меняет внешнее состояние)

Чистоту функции определяют две основные характеристики.

Характеристика 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

  1. Пиши чистые функции по умолчанию
  2. Избегай изменения параметров:
    // ПЛОХО
    function updateUser(user) {
      user.name = 'New Name';
    }
    // ХОРОШО
    function updateUser(user) {
      return { ...user, name: 'New Name' };
    }
    
  3. Передавай зависимости как параметры
  4. Возвращай новые объекты вместо мутирования
  5. Используй чистые функции в React компонентах

Вывод

Функция является чистой, когда она детерминирована (одинаковый вход = одинаковый выход) и не имеет побочных эффектов. Чистые функции — это основа предсказуемого, тестируемого и масштабируемого кода в JavaScript и особенно в React.