Что такое чистая функция и какие у нее признаки
Что проверяют
Знаете ли вы два признака и понимаете ли, зачем чистота нужна на практике, особенно в React.
Как отвечать
Признаков ровно два:
- Детерминированность: одни и те же аргументы всегда дают один и тот же результат.
- Отсутствие побочных эффектов: функция ничего не меняет за своими пределами.
Из этого следует, что чистая функция не читает изменяемое внешнее состояние, не изменяет аргументы, не обращается к сети и хранилищу, не пишет в консоль, не использует Math.random и Date.now.
const sum = (a, b) => a + b; // чистая
const addItem = (list, x) => [...list, x]; // чистая: новый массив
const push = (list, x) => { list.push(x); }; // нечистая: меняет аргументЗачем это нужно:
- тестируется без окружения: вход и ожидаемый выход, никаких заглушек;
- можно мемоизировать: результат зависит только от аргументов;
- можно переупорядочивать и выполнять параллельно без гонок;
- читается локально: чтобы понять функцию, не нужно знать состояние остального приложения.
Отдельно про React, потому что там это не теория:
- функция компонента обязана быть чистой во время рендера. Один и тот же набор пропсов и состояния должен давать одно и то же дерево. Побочные эффекты выносятся в
useEffect, а мутация пропсов или внешней переменной прямо в теле компонента ломает как раз это правило; - редьюсер обязан быть чистым: поэтому запросы к серверу живут в санках, а не внутри него;
- на чистоте держится и режим строгой проверки, который намеренно вызывает рендер дважды, и компилятор React 19, автоматически расставляющий мемоизацию.
Полностью чистой программы не бывает: эффекты нужны, их просто выносят на края и держат тонким слоем вокруг чистого ядра.
Где спотыкаются
Считают функцию чистой, хотя она изменяет переданный массив.
Не относят чтение изменяемой глобальной переменной к нарушению.
Делают запрос прямо в теле компонента.
Думают, что чистота это про отсутствие мутаций, забывая про детерминированность.