Перейти к содержимому

25. Каррирование и частичное применение

JavaScript: Мозги. Урок: Каррирование и частичное применение

Заголовок раздела «JavaScript: Мозги. Урок: Каррирование и частичное применение»

Иллюстрация к уроку Каррирование и частичное применение – мощные техники функционального программирования, позволяющие создавать более гибкий и переиспользуемый код. Они позволяют “зафиксировать” часть аргументов функции, создавая новые функции с меньшей арностью (количеством ожидаемых аргументов).

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

// Функция, принимающая два аргумента
function add(x, y) {
return x + y;
}
// Каррированная версия функции add
function curriedAdd(x) {
return function(y) {
return x + y;
};
}
// Использование
const add5 = curriedAdd(5); // add5 теперь функция, ожидающая один аргумент
console.log(add5(3)); // Выводит 8
console.log(curriedAdd(10)(2)); // Выводит 12

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

function greet(greeting, name) {
return `${greeting}, ${name}!`;
}
// Частичное применение с использованием bind
const sayHello = greet.bind(null, "Hello"); // "Hello" зафиксирован как первый аргумент
console.log(sayHello("Alice")); // Выводит "Hello, Alice!"
console.log(sayHello("Bob")); // Выводит "Hello, Bob!"
// Частичное применение без bind
function partialGreet(greeting) {
return function(name) {
return `${greeting}, ${name}!`;
}
}
const sayGoodMorning = partialGreet("Good morning");
console.log(sayGoodMorning("Eve")); // Выводит "Good morning, Eve!"
// Пример: функция для создания тегов HTML
function createTag(tag, attributes, content) {
let attrString = "";
for (const key in attributes) {
attrString += ` ${key}="${attributes[key]}"`;
}
return `<${tag}${attrString}>${content}</${tag}>`;
}
// Каррированная версия
function curriedCreateTag(tag) {
return function(attributes) {
return function(content) {
let attrString = "";
for (const key in attributes) {
attrString += ` ${key}="${attributes[key]}"`;
}
return `<${tag}${attrString}>${content}</${tag}>`;
};
};
}
const createDiv = curriedCreateTag("div");
const divWithClass = createDiv({ class: "container" });
console.log(divWithClass("Hello, world!")); // Выводит <div class="container">Hello, world!</div>
// Пример: частичное применение с bind для валидации
function validateInput(validator, input) {
return validator(input);
}
function isEmailValid(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
const validateEmail = validateInput.bind(null, isEmailValid);
console.log(validateEmail("[email protected]")); // Выводит true
console.log(validateEmail("invalid-email")); // Выводит false

Во фреймворке React, каррирование и частичное применение часто используются при работе с компонентами высшего порядка (Higher-Order Components - HOC). HOC позволяют обернуть компонент для добавления дополнительной функциональности, например, авторизации или логирования. Частичное применение позволяет передавать параметры в HOC, создавая кастомизированные обертки для компонентов.

В Redux, connect функция использует частичное применение для связывания состояния Redux с компонентами React. connect принимает mapStateToProps и mapDispatchToProps как аргументы и возвращает новую функцию, которая, в свою очередь, принимает компонент React для обертывания.

  • Каррирование преобразует функцию с несколькими аргументами в последовательность функций с одним аргументом.
  • Частичное применение позволяет “зафиксировать” часть аргументов функции.
  • bind – удобный метод для частичного применения в JavaScript.
  • Эти техники повышают переиспользуемость и читаемость кода.
  • Часто используются во фреймворках React и Redux.