> Что делать в функции каррирования в JavaScript при получении достаточного количества аргументов (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Яндекс
Стек: JavaScript
> Пример ответа
Короткий ответ
При получении достаточного количества аргументов функция каррирования должна вызвать исходную функцию с накопленными аргументами и вернуть результат. Если аргументов недостаточно, возвращается новая функция, ожидающая оставшиеся аргументы. Ключевой момент - правильно определить момент, когда количество переданных аргументов достигло или превысило ожидаемое (обычно через fn.length или явно заданное число).
Подробное объяснение
Каррирование - это трансформация функции от n аргументов в последовательность функций, каждая от одного аргумента. В JavaScript каррирование обычно реализуется через замыкание, которое накапливает аргументы до тех пор, пока их количество не станет достаточным для вызова исходной функции.
Механизм работы:
- Внутренняя функция хранит накопленные аргументы в массиве через замыкание
- При каждом вызове новые аргументы добавляются в этот массив
- Проверяется условие: если длина массива достигла ожидаемого количества (обычно
fn.lengthдля обычных функций или явно заданногоarity), вызывается исходная функция черезfn.apply(this, args) - Если аргументов недостаточно, возвращается новая функция, которая продолжит накопление
Важный нюанс: fn.length не учитывает rest parameters (...args) и значения по умолчанию. Для таких случаев нужно передавать arity явно. Также стоит учитывать контекст this - в стрелочных функциях он не привязывается, а в обычных может потребоваться передача через bind или сохранение.
На практике
В реальных проектах каррирование чаще всего используется не в чистом виде, а как часть функционального подхода - например, для создания специализированных функций из общих. Типичный сценарий - логирование с предустановленным уровнем:
JAVASCRIPTconst 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)); // 6console.log(curriedSum(1, 2)(3)); // 6console.log(curriedSum(1)(2, 3)); // 6// С явной arity для функций с rest parametersfunction 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 их просто проигнорирует)
- Создавать бесконечную рекурсию из-за неправильного условия остановки
> Похожие задачи по frontend
Как реализовать обработку клика на любой div внутри root и выводить в консоль только id этого div в JavaScript
Как рекурсивно проверять условие повторных запросов с учётом счётчика попыток в JavaScript
Блокируется ли поток при выполнении асинхронного кода после синхронного в JavaScript
Может ли при push в массив в JavaScript происходить копирование данных
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью