Что такое каррирование (currying)?

👨‍💻 Frontend Developer 🟠 Может встретиться 🎚️ Средний
#JavaScript #Функции #База JS

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

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

// Обычная функция
function add(a, b, c) {
  return a + b + c;
}
 
// Каррированная функция
function curryAdd(a) {
  return function(b) {
    return function(c) {
      return a + b + c;
    };
  };
}
 
// Использование
console.log(add(1, 2, 3));        // 6
console.log(curryAdd(1)(2)(3));   // 6
console.log(curryAdd(1)(2));      // function (ожидает третий аргумент)

Полный ответ

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

Что такое каррирование

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

Простые примеры

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

// Обычная функция сложения
function sum(a, b) {
  return a + b;
}
 
// Каррированная версия
function currySum(a) {
  return function(b) {
    return a + b;
  };
}
 
// Использование
console.log(sum(2, 3));      // 5
console.log(currySum(2)(3)); // 5

Каррирование с тремя параметрами

// Обычная функция
function multiply(a, b, c) {
  return a * b * c;
}
 
// Каррированная версия
function curryMultiply(a) {
  return function(b) {
    return function(c) {
      return a * b * c;
    };
  };
}
 
// Использование
console.log(multiply(2, 3, 4));        // 24
console.log(curryMultiply(2)(3)(4));   // 24

Как работает каррирование

Пошаговое выполнение

function add(a) {
  return function(b) {
    return a + b;
  };
}
 
const add5 = add(5);  // Возвращается функция, ожидающая b
const result = add5(3); // 8 (5 + 3)
 
// Или сразу:
const result2 = add(5)(3); // 8

Создание специализированных функций

function multiply(a) {
  return function(b) {
    return a * b;
  };
}
 
// Создаем специализированные функции
const double = multiply(2);   // Удвоить число
const triple = multiply(3);   // Утроить число
 
console.log(double(5));  // 10
console.log(triple(5));  // 15

Когда использовать каррирование

Для создания переиспользуемых функций

// Каррированная функция для проверки диапазона
function inRange(min) {
  return function(max) {
    return function(value) {
      return value >= min && value <= max;
    };
  };
}
 
// Создаем специализированные проверки
const isChildAge = inRange(0)(12);     // Для детей 0-12 лет
const isAdultAge = inRange(18)(100);   // Для взрослых 18-100 лет
 
console.log(isChildAge(8));   // true
console.log(isAdultAge(25));  // true

Для функционального программирования

// Каррированная функция для фильтрации массивов
function filterBy(property) {
  return function(value) {
    return function(array) {
      return array.filter(item => item[property] === value);
    };
  };
}
 
const users = [
  { name: 'Иван', age: 25 },
  { name: 'Петр', age: 30 },
  { name: 'Мария', age: 25 }
];
 
// Создаем фильтр для возраста 25
const filterByAge25 = filterBy('age')(25);
const result = filterByAge25(users);
// [{ name: 'Иван', age: 25 }, { name: 'Мария', age: 25 }]

Частые ошибки

Путаница с синтаксисом

function add(a) {
  return function(b) {
    return a + b;
  };
}
 
// ❌ Неправильное использование
// console.log(add(5)); // [Function] (не число!)
 
// ✅ Правильное использование
console.log(add(5)(3)); // 8

Забыть про промежуточные функции

function multiply(a) {
  return function(b) {
    return a * b;
  };
}
 
// ❌ Ошибка
// const result = multiply(5, 3); // undefined
 
// ✅ Правильно
const result = multiply(5)(3); // 15

Простые правила

  1. Каррирование — разбивает функцию на цепочку функций с одним параметром 🧱
  2. Поэтапность — каждый вызов возвращает следующую функцию в цепочке 🔗
  3. Специализация — позволяет создавать частично применённые функции 🎯
  4. Переиспользование — удобно для создания специализированных версий функций ♻️
  5. Функциональное программирование — основа многих функциональных техник 🧠

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


Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪