Функциональное программирование
Функциональный стиль в JavaScript опирается на то, что функции — значения первого класса: их можно составлять, оборачивать и настраивать. В основе всего лежит чистая функция — предсказуемая, без побочных эффектов. Из неё вырастают композиция, каррирование, частичное применение и мемоизация.
Тема насыщена терминами, которые кандидаты путают: каррирование против частичного применения, compose против pipe, примеси против наследования. Каждый слой ниже разводит пару похожих понятий по механике — а не по красивому определению. Отдельно стоит арность (fn.length), потому что каррирование и частичное применение опираются на число параметров.
Карта темы
- Чистые функции — детерминированный результат без побочных эффектов и почему это база всего стиля.
- Композиция функций —
composeиpipe, объединяющие функции в конвейер, и их направления. - Каррирование — превращение n-арной функции в цепочку унарных, вызываемую как
f(1)(2)(3). - Частичное применение — фиксация части аргументов заранее и отличие от каррирования.
- Арность функции — число параметров и что на самом деле считает
fn.length. - Мемоизация — кэш результата по аргументам, требование чистоты и подвох с ключом.
- Примеси — копирование методов через
Object.assignвместо наследования.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
| Считать функцию, мутирующую аргумент, чистой | Скрытые побочные эффекты, невоспроизводимые тесты |
| Путать каррирование и частичное применение | Неверный ответ на классический вопрос интервью |
Перепутать направление compose и pipe | Конвейер выполняет шаги в обратном порядке |
| Мемоизировать нечистую функцию | Кэш возвращает устаревшие значения |
| Наивно ключевать объекты в кэше | Разные объекты сталкиваются как [object Object] |
Ждать super после примеси | Object.assign копирует метод, доступа к исходному нет |
Значение для собеседований
Функциональную секцию любят за пары почти-синонимов: интервьюер называет два термина и ждёт, что вы разведёте их по механике. Ответ «каррирование берёт по одному аргументу за вызов, а частичное применение фиксирует сколько угодно разом» ценнее любого определения из учебника.
Что обычно проверяют:
- Определение чистоты через детерминизм и отсутствие побочных эффектов; примеры нечистых функций (
Date.now(),Math.random(), мутация). - Разницу каррирования и частичного применения; роль замыкания в обоих.
- Направления
compose(справа налево) иpipe(слева направо). - Когда мемоизация окупается, а когда только тратит память; подвох ключа кэша.
Типичный неверный ответ: «мемоизация ускоряет любую функцию». Нет — только чистую, чей результат зависит лишь от аргументов, и только когда одни и те же входы дорого пересчитывать и они повторяются. Иначе кэш растёт без выгоды.