> Что делать в функции каррирования в JavaScript при получении достаточного количества аргументов (JavaScript)

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

Компании: Яндекс

Стек: JavaScript

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

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

При получении достаточного количества аргументов функция каррирования должна вызвать исходную функцию с накопленными аргументами и вернуть результат. Если аргументов недостаточно, возвращается новая функция, ожидающая оставшиеся аргументы. Ключевой момент - правильно определить момент, когда количество переданных аргументов достигло или превысило ожидаемое (обычно через fn.length или явно заданное число).

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

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

Механизм работы:

  1. Внутренняя функция хранит накопленные аргументы в массиве через замыкание
  2. При каждом вызове новые аргументы добавляются в этот массив
  3. Проверяется условие: если длина массива достигла ожидаемого количества (обычно fn.length для обычных функций или явно заданного arity), вызывается исходная функция через fn.apply(this, args)
  4. Если аргументов недостаточно, возвращается новая функция, которая продолжит накопление

Важный нюанс: fn.length не учитывает rest parameters (...args) и значения по умолчанию. Для таких случаев нужно передавать arity явно. Также стоит учитывать контекст this - в стрелочных функциях он не привязывается, а в обычных может потребоваться передача через bind или сохранение.

На практике

В реальных проектах каррирование чаще всего используется не в чистом виде, а как часть функционального подхода - например, для создания специализированных функций из общих. Типичный сценарий - логирование с предустановленным уровнем:

JAVASCRIPT
const log = (level) => (message) => console[level](message);
const info = log('info');
info('Server started'); // console.info('Server started')

Библиотеки вроде Lodash предоставляют готовый _.curry, который автоматически определяет момент вызова. В production-коде обычно используют готовые реализации, а не пишут свои, чтобы избежать edge cases с this, length и rest parameters.

Пример кода

JAVASCRIPT
// Базовая реализация каррирования
function curry(fn, arity = fn.length) {
return function curried(...args) {
if (args.length >= arity) {
return fn.apply(this, args);
} else {
return function(...nextArgs) {
return curried.apply(this, args.concat(nextArgs));
};
}
};
}
// Использование
function sum(a, b, c) {
return a + b + c;
}
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 6
console.log(curriedSum(1, 2)(3)); // 6
console.log(curriedSum(1)(2, 3)); // 6
// С явной arity для функций с rest parameters
function logAll(...args) {
console.log(args);
}
const curriedLogAll = curry(logAll, 3);
curriedLogAll('a')('b')('c'); // ['a', 'b', 'c']

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

Начни с чёткого определения момента вызова: когда количество аргументов достигает arity. Покажи понимание разницы между fn.length и явной arity для функций с дефолтными параметрами. Упомяни, что в стрелочных функциях this не переопределяется, а в обычных нужно сохранять контекст через apply или call. Хорошо добавить про практическое применение - создание частично применённых функций для обработчиков событий или middleware. Если спросят про производительность, отметь, что каждая вложенная функция создаёт новый closure, но в большинстве случаев это не критично.

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

Проверяется понимание замыканий, механизма накопления аргументов и разницы между частичным применением и каррированием. Интервьюер хочет увидеть, что ты знаешь, как работает fn.length, как обрабатывать rest parameters, и понимаешь, что каррирование - это не магия, а просто функции, возвращающие функции до достижения нужного числа аргументов. Также оценивается способность объяснить, когда каррирование полезно, а когда избыточно.

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

  • Путать каррирование с частичным применением: в каррировании каждая функция принимает ровно один аргумент, а частичное применение фиксирует часть аргументов сразу
  • Забывать про контекст this при использовании обычных функций
  • Полагаться только на fn.length без учёта функций с rest parameters или дефолтными значениями
  • Не обрабатывать случай, когда аргументов передано больше, чем нужно - лишние аргументы должны передаваться в исходную функцию (JavaScript их просто проигнорирует)
  • Создавать бесконечную рекурсию из-за неправильного условия остановки

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

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