> В чем разница каррирования и частичного применения в JavaScript (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: циан

Стек: JavaScript

> Пример ответа

Короткий ответ

Каррирование - это преобразование функции от нескольких аргументов в последовательность функций, каждая из которых принимает один аргумент. Частичное применение - это фиксация части аргументов функции с возвратом функции для оставшихся. Ключевое различие: каррирование всегда возвращает функции с одним аргументом, а частичное применение может зафиксировать произвольное количество аргументов и вернуть функцию с любым оставшимся числом.

Подробное объяснение

Каррирование - это чисто математическая трансформация: f(a, b, c) превращается в f(a)(b)(c). Каждый вызов возвращает новую функцию, ожидающую ровно один следующий аргумент. Процесс продолжается, пока не будут собраны все аргументы, после чего выполняется исходная функция.

Частичное применение - это более прагматичный подход: вы берете функцию и "замораживаете" некоторые её аргументы, получая функцию с меньшим количеством параметров. Например, partial(f, 1, 2) вернет функцию, которая ожидает только третий аргумент.

Основные различия:

  • Количество аргументов на шаг: каррирование строго по одному, частичное применение - произвольное количество.
  • Форма вызова: каррированная функция вызывается цепочкой f(a)(b)(c), частично примененная - f(1, 2)(c) или f(1)(2, c).
  • Реализация: каррирование обычно автоматическое (через curry), частичное применение - через bind или явную обертку.
  • Семантика: каррирование меняет сигнатуру функции, частичное применение - только фиксирует значения.

На практике каррирование удобно для композиции функций и point-free стиля, а частичное применение - для создания специализированных версий функций с предзаданными параметрами.

На практике

В реальном коде каррирование редко используется в чистом виде, потому что оно усложняет чтение и отладку. Частичное применение через Function.prototype.bind встречается чаще - например, для передачи предзаданных аргументов в колбэки или для создания конфигурируемых обработчиков.

Каррирование полезно в функциональных библиотеках (Ramda, lodash/fp), где оно сочетается с композицией. Частичное применение - в повседневном коде для упрощения вызовов с повторяющимися параметрами.

Важно понимать, что в JavaScript нет встроенного каррирования - его нужно реализовывать вручную или использовать библиотеки. При этом bind дает частичное применение "из коробки".

Пример кода

JAVASCRIPT
// Обычная функция
function add(a, b, c) {
return a + b + c;
}
// Каррирование - строго по одному аргументу
function curryAdd(a) {
return function(b) {
return function(c) {
return a + b + c;
};
};
}
curryAdd(1)(2)(3); // 6
// Частичное применение - фиксируем часть аргументов
const addWithOne = add.bind(null, 1);
addWithOne(2, 3); // 6 - осталось два аргумента
const addWithOneAndTwo = add.bind(null, 1, 2);
addWithOneAndTwo(3); // 6 - остался один аргумент
// Универсальная функция каррирования
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return (...more) => curried.apply(this, args.concat(more));
};
}
const curriedAdd = curry(add);
curriedAdd(1)(2)(3); // 6
curriedAdd(1, 2)(3); // 6 - тоже работает

Как отвечать на собеседовании

Начните с четкого определения обоих понятий. Подчеркните главное различие: каррирование - это трансформация сигнатуры, частичное применение - фиксация значений. Приведите пример с bind для частичного применения и простую реализацию каррирования. Упомяните, что каррирование в JS требует ручной реализации, а частичное применение доступно через встроенный bind. Если спросят про практическое применение - скажите про композицию функций и специализацию обработчиков.

Что проверяет интервьюер

Интервьюер оценивает:

  • понимание разницы между трансформацией функции и фиксацией аргументов;
  • знание встроенных возможностей JS (bind, apply, call);
  • способность реализовать каррирование вручную;
  • понимание, когда какой подход уместен;
  • владение функциональными концепциями на уровне senior.

Типичные ошибки

  • Смешивание понятий: утверждение, что каррирование и частичное применение - одно и то же.
  • Утверждение, что bind - это каррирование (это частичное применение).
  • Игнорирование разницы в количестве аргументов на шаг.
  • Попытка объяснить каррирование без примера кода.
  • Забывают упомянуть, что каррирование в JS не встроено и требует реализации.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью