В JavaScript очень легко дублировать одно и то же условие в разных местах. Сначала мы пишем общий filter, потом второй, потом третий почти такой же, а через месяц уже неясно, где одинаковая логика, а где начало расхождения.
Partial application помогает не копировать такие куски заново. Мы берем общую функцию, фиксируем часть аргументов и получаем новую, более конкретную функцию с понятным назначением.
Это не про “магическое” функциональное программирование. Это про то, как превращать слишком общие функции в говорящие предикаты и удобные строительные блоки.
Обновлено 17 марта 2026: переписаны примеры, убраны нерабочие фрагменты и уточнено различие между partial application, currying и
bind.
Чем partial application отличается от currying
Эти термины часто смешивают, но это не одно и то же.
curryingпреобразует функцию с несколькими аргументами в цепочку функций по одному аргументу;partial applicationфиксирует часть аргументов и возвращает новую функцию, которая ждет остальные.
Currying часто делает partial application удобнее, но частичное применение возможно и без каррирования.
Если хочешь глубже разобрать сам currying, посмотри Каррирование функций в JavaScript.
Самый полезный сценарий: говорящие предикаты
Допустим, у нас есть общая функция, которая проверяет тип задачи.
function isTaskOfType(type, task) {
return task.type === type;
}Вызов напрямую выглядит слишком общо:
tasks.filter((task) => isTaskOfType("NC", task));С частичным применением можно зафиксировать тип один раз и получить функцию, которая уже отражает смысл.
const partial = (fn, fixedArg) => (value) => fn(fixedArg, value);
function isTaskOfType(type, task) {
return task.type === type;
}
const isNewContentTask = partial(isTaskOfType, "NC");
tasks.filter(isNewContentTask);Разница не только в краткости. isNewContentTask хорошо читается в любом месте кода и снижает риск, что ты начнешь копировать строковый литерал "NC" по проекту.
Partial application через замыкание
На практике partial application часто выглядит просто как функция, которая возвращает другую функцию и хранит заранее переданное значение в замыкании.
const withPrefix = (prefix) => (message) => `${prefix}: ${message}`;
const asError = withPrefix("Error");
const asInfo = withPrefix("Info");
console.log(asError("Missing config")); // Error: Missing config
console.log(asInfo("Server started")); // Info: Server startedЗдесь prefix зафиксирован заранее. Каждая новая функция переиспользует эту часть конфигурации без повторения.
Partial application в реальном коде
Обычно этот прием полезен в трех местах:
Фильтрация и поиск
Когда один и тот же критерий используется во многих filter, find или some.
Настройка API и адаптеров
Когда нужно один раз зафиксировать baseUrl, feature flag, logger или формат данных.
Подготовка функций для композиции
Когда ты хочешь собрать pipeline из маленьких шагов и заранее подставить конфигурацию.
Например:
const map = (fn) => (list) => list.map(fn);
const prop = (key) => (obj) => obj[key];
const getName = prop("name");
const getNames = map(getName);
getNames([
{ name: "Alex" },
{ name: "Julia" },
]); // ["Alex", "Julia"]Здесь partial application делает маленькие функции переиспользуемыми и готовыми к композиции.
Когда достаточно bind
Иногда partial application не требует собственной утилиты. В простых случаях хватает bind.
const multiply = (x, y) => x * y;
const multiplyBy2 = multiply.bind(null, 2);
multiplyBy2(3); // 6
multiplyBy2(5); // 10bind удобен, когда ты работаешь с обычной функцией и хочешь быстро зафиксировать первые аргументы. Но если код уже строится вокруг композиции, каррированных функций и data-last сигнатур, собственные небольшие утилиты часто читаются лучше.
Ошибки, которые делают partial application бесполезным
Частичное применение не помогает автоматически. Его легко превратить в еще один слой сложности.
Осторожнее, если:
- новая функция получила абстрактное имя и перестала объяснять смысл;
- partial application используется один раз и только скрывает простой аргумент;
- ради красивой формы приходится угадывать порядок аргументов;
- данные передаются не последним аргументом и функцию неудобно собирать в pipeline.
Самый хороший результат получается там, где новая функция начинает читаться как отдельное правило домена.
Partial application полезен тогда, когда помогает превратить слишком общую функцию в конкретную и говорящую. Он снижает копипасту, делает код легче для чтения и хорошо работает вместе с замыканиями, bind и функциональной композицией.
Если нужен быстрый ориентир, ищи повторяющиеся условия и повторяющуюся конфигурацию. Именно там partial application почти всегда окупается.