Каррирование

04-11-24 09:01:46


Image for the Каррирование

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

Базовый пример каррирования

Начнем с простой функции, которая принимает два аргумента и возвращает их сумму:

function add(x, y) {
return x + y;
}

console.log(add(3, 5)); // Вывод: 8

С каррированием мы можем преобразовать add в функцию, которая принимает один аргумент и возвращает другую функцию, которая принимает второй аргумент:

function curriedAdd(x) {
return function(y) {
return x + y;
};
}

const addThree = curriedAdd(3);
console.log(addThree(5)); // Вывод: 8
console.log(curriedAdd(4)(6)); // Вывод: 10

Теперь curriedAdd принимает только один аргумент и возвращает новую функцию, которая принимает второй аргумент. Это позволяет нам «частично применять» функцию, задавая один аргумент за раз.

Написание общей функции каррирования

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

function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return function(...nextArgs) {
return curried.apply(this, args.concat(nextArgs));
};
}
};
}

// Пример использования
function multiply(a, b, c) {
return a * b * c;
}

const curriedMultiply = curry(multiply);

console.log(curriedMultiply(2)(3)(4)); // Вывод: 24
console.log(curriedMultiply(2, 3)(4)); // Вывод: 24
console.log(curriedMultiply(2, 3, 4)); // Вывод: 24

Применение каррирования в реальных задачах

Каррирование имеет множество практических применений в JavaScript.

Обработка событий и манипуляции с DOM

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

function addEventListenerWithLog(element, event) {
return function(logMessage) {
return function(callback) {
element.addEventListener(event, (e) => {
console.log(logMessage);
callback(e);
});
};
};
}

const button = document.querySelector('button');
const logClick = addEventListenerWithLog(button, 'click')('Button clicked!');
logClick((e) => alert('Button was clicked!'));

// Вывод при нажатии кнопки:
// Консоль: Button clicked!
// Окно alert: Button was clicked!

Композиция функций

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

const add = (x) => (y) => x + y;
const multiply = (x) => (y) => x * y;
const increment = add(1);
const double = multiply(2);

const numbers = [1, 2, 3, 4];
const result = numbers.map(increment).map(double);

console.log(result); // Вывод: [4, 6, 8, 10]

Конфигурация и инициализация

​Каррирование полезно, когда вам нужно настраивать функцию.