Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про JavaScript: currying, partial application, closure, higher-order function, functional programming

Как хранить промежуточные аргументы при каррировании?

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

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

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

Длинный ответ

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

Механизм хранения через замыкания

Когда каррированная функция вызывается с аргументом, она возвращает новую функцию. Эта новая функция имеет доступ к аргументу (или аргументам), переданным на предыдущем шаге, благодаря замыканию. Замыкание — это комбинация функции и лексического окружения, в котором она была объявлена. Это окружение содержит все локальные переменные, которые были доступны на момент создания функции, включая параметры внешней функции.

Пример каррирования в JavaScript

Рассмотрим простую функцию сложения и её каррированную версию:

// Обычная функция
function add(a, b) {
    return a + b;
}

// Каррированная версия
function curryAdd(a) {
    // Аргумент 'a' сохраняется в замыкании
    return function(b) {
        // Внутренняя функция имеет доступ к 'a'
        return a + b;
    };
}

const addFive = curryAdd(5); // '5' хранится в замыкании addFive
console.log(addFive(3)); // 8
console.log(addFive(10)); // 15

В этом примере значение 5 хранится в замыкании функции, которую возвращает curryAdd(5). Каждый вызов addFive использует это сохранённое значение.

Универсальный каррирующий декоратор

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

function curry(fn) {
    return function curried(...args) {
        // Если переданных аргументов достаточно, вызываем исходную функцию
        if (args.length >= fn.length) {
            return fn.apply(this, args);
        } else {
            // Иначе возвращаем новую функцию, которая запомнит текущие аргументы
            return function(...args2) {
                // Все аргументы (старые и новые) хранятся в замыкании
                return curried.apply(this, args.concat(args2));
            };
        }
    };
}

// Использование
function sum(a, b, c) {
    return a + b + c;
}

const curriedSum = curry(sum);
const addTwo = curriedSum(2); // Запоминает 2
const addTwoAndThree = addTwo(3); // Запоминает 2 и 3
console.log(addTwoAndThree(5)); // 10 (2+3+5)

Здесь промежуточные аргументы накапливаются в массиве args, который сохраняется в замыкании каждой возвращаемой функции.

Где применяется каррирование

  • Создание специализированных функций: Фиксация части параметров (например, функция логирования с префиксом).
  • Функциональная композиция: Упрощение комбинирования функций в конвейеры.
  • Отложенные вычисления: Построение вычисления по шагам, когда не все данные доступны сразу.

Итог: Каррирование использует замыкания для хранения промежуточных аргументов, что позволяет создавать гибкие и переиспользуемые функции. Применяйте его, когда нужно создавать множество похожих функций с частично заданными параметрами или строить цепочки функциональных преобразований.

Уровень

  • Рейтинг:

    3

  • Сложность:

    5

Навыки

  • JavaScript

    JavaScript

Ключевые слова

#currying

#partial application

#closure

#higher-order function

#functional programming

Подпишись на React Developer в телеграм