Javascript: примеры использования каррирования

Обычно я понимаю каррирование и то, как оно использует замыкания:

function foo(a) {
  return function(b) {
     return function(c) {
         return a*b*c;
     }
   }
}

как бы это было максимизировано? Разве это не сэкономило бы рабочее время, если бы ожидалось получение множества одних и тех же аргументов?

Например, если бы вы знали, что 5 всегда будет первым аргументом:

let first = foo(5);

тогда вы можете сделать: first(8)(12); или что-то еще для последних 2 аргументов.

Однако, если вы не ожидаете одних и тех же аргументов и каждый раз используете их следующим образом:

foo(3)(5)(9);

разве это не противоречит цели и не является ли это тем же самым, что и создание обычной функции, которая принимает только 3 аргумента?

Я просто пытаюсь понять вариант использования этого, потому что в моей голове это кажется действительно ограниченным.

Ну, иногда это имеет смысл, когда вы создаете вспомогательные функции для создания обратных вызовов для других функций, например. array.sort( sortBy("name") ). Однако во многих случаях имеет смысл иметь одну функцию с несколькими параметрами. Так что вы правы, это очень ограничено.

Jonas Wilms 13.12.2020 20:45

В идеале вы должны использовать автокаррирование, чтобы вы могли использовать функцию любым способом, например f(a, b)(c), и все это должно работать одинаково. См. Например, Лодаш curry.

elclanrs 13.12.2020 20:49
stackoverflow.com/a/37764035/3757232
Jared Smith 13.12.2020 20:49
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
489
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это полезно при частичном применении или сочинении. Вы можете сделать что-то вроде этого, например

const arr = [1,2,3,4]

const curry = (fn, ...a) => fn.length > a.length ? (...b) => curry(fn,...a.concat(b)) : fn.apply(null,a)

const add = curry((a,b) => a+b)

console.info(arr.map(add(5)))

const compose = (...fns) => fns.reduce((f,g) => b => f(g(b)))

console.info(arr.map(compose(add(5),add(2))))

Однако напрашивается вопрос, не так ли? «Случаи частичного применения»

Robert Harvey 13.12.2020 20:55

Вариант без каррирования будет: arr.reduce((a, b) => a + b) ...

Jonas Wilms 13.12.2020 20:55

Вот несколько реальных примеров, где я использую это все время. Во-первых, на переднем конце:

debounce(someEventHandler, someTimeout);
debounce(someOtherEventHandler, someTimeout);
debounce(yetAnotherEventHandler, someTimeout);

Допустим, я хочу, чтобы все мои обработчики клавиатуры отключались на 250 мс. Я могу писать это снова и снова, или...

const debounceBy250 = curry(flip(debounce))(250);

Теперь код стал лаконичнее и понятнее. Во-вторых, на бэкэнде допустим, что у вас есть код, который получает тайм-аут запроса (база данных, REST, TCP, что угодно) из переменной окружения. Как и выше, вы можете либо добавить это везде, где он используется, либо частично применить его к функциям, которые его используют.

Для случая, когда кто-то на самом деле использовал его, но не знал, как он называется, см. мой ответ здесь на этот не совсем повторяющийся вопрос.

Другие вопросы по теме