Введение
Откуда берется карри
карри, которыйCurryingтранслитерация.CurryingЭто технология реализации многопараметрических функций на уровне принципа компиляции.
говорящийКаррирование в JavaScriptПрежде, давайте поговорим об оригиналеCurryingЧто это такое и откуда взялось.
В процессе кодирования мы, как программисты, по сути, разбиваем сложную проблему на множество программируемых небольших задач.
CurryingПредоставляет идею реализации рекурсивной деградации для реализации многопараметрических функций——Преобразование функции, которая принимает несколько аргументов, в функцию, которая принимает один аргумент (первый аргумент исходной функции) и возвращает новую функцию, которая принимает оставшиеся аргументы и возвращает результат., в некоторых языках программирования (например, Haskell) черезCurryingТехнология поддерживает языковую функцию функций с несколькими аргументами.
такCurryingПервоначально технология на уровне принципов компиляции, целью которой являетсяРеализовать функции с несколькими аргументами.
Куда уходит карри?
В Haskell функции являются гражданами первого класса.CurryingТехнология с уровня принципа компиляции стала особенностью языка. На уровне особенностей языка,Curryingчто это?
В книге "В основном адекватный путеводитель" это подытожено такCurrying——Вызовите его, передав функции только подмножество аргументов, и пусть она вернет функцию для обработки остальных аргументов..
такCurryingОн родился в ответ на функциональное программирование, и сCurryingПозже все отправились исследовать, чтобы узнать о его использовании и значении. Затем из-за этих применений и значений люди активно расширили его на другие языки программирования.
Реализация каррирования в JavaScript
Чтобы достичьВызовите его, передав функции только подмножество аргументов, и пусть она вернет функцию для обработки остальных аргументов.характеристики, описываемые этим предложением.
Сначала напишем функцию, реализующую сложениеadd
:
function add (x, y) {
return (x + y)
}
Теперь мы непосредственно реализуемCurryingизadd
функция с именемcurriedAdd
, то по приведенному выше определениюcurriedAdd
Необходимо выполнить следующие условия:
curriedAdd(1)(3) === 4
// true
var increment = curriedAdd(1)
increment(2) === 3
// true
var addTen = curriedAdd(10)
addTen(2) === 12
// true
соответствовать вышеперечисленным условиямcurriedAdd
Функцию можно реализовать с помощью следующего фрагмента кода:
function curriedAdd (x) {
return function(y) {
return x + y
}
}
Конечно, у приведенной выше реализации есть некоторые проблемы: она не универсальна, и мы не хотим делать это, перекодируя саму функцию.Curryingизменять.
но этоcurriedAdd
РеализацияCurryingоснова —CurryingФункция ленивых вычислений требует использования областей видимости в JavaScript — говоря более неформально, нам нужно использовать области видимости для сохранения последнего переданного параметра.
правильноcurriedAdd
Чтобы абстрагироваться, вы можете получить следующие функцииcurrying
:
function currying (fn, ...args1) {
return function (...args2) {
return fn(...args1, ...args2)
}
}
var increment = currying(add, 1)
increment(2) === 3
// true
var addTen = currying(add, 10)
addTen(2) === 12
// true
В этой реализацииcurrying
Возвращаемое значение функции на самом деле является функцией, которая принимает оставшиеся аргументы и немедленно возвращает вычисленное значение.т. е. его возвращаемое значение не каррируется автоматически. Таким образом, мы можем автоматически каррировать возвращаемую функцию каррирования с помощью рекурсии.изменять.
function trueCurrying(fn, ...args) {
if (args.length >= fn.length) {
return fn(...args)
}
return function (...args2) {
return trueCurrying(fn, ...args, ...args2)
}
}
Вышеуказанная функция короткая, но реализованнаяCurryingосновная идея. Основная идея метода curry в Lodash, широко используемой библиотеке в JavaScript, мало чем отличается от приведенной выше:Сравните общее количество принятых параметров несколько раз с количеством входных параметров при определении функции.Когда количество принятых параметров больше или равно количеству входящих параметров функции каррирования, возвращается результат расчета, в противном случае , возвращается функция, которая продолжает принимать параметры.
Реализовано в ЛодашCurryingФрагмент длиннее, потому что он учитывает больше вещей, таких как привязка переменной this и т. д. Фрагменты кода в Lodash не будут публиковаться здесь напрямую. Заинтересованные студенты могут посмотреть исходный код Lodash, чтобы сравнить различия между двумя реализациями.
тем не мениеCurryingОпределение и реализация не являются самыми важными, в этой статье основное внимание уделяется разработке:Он может решить проблемы при кодировании и разработке, а при возникновении различных проблем выбрать подходящую каррировку для наиболее подходящего решения проблемы..
Каррирование сценариев использования
Повторное использование параметра
Фиксированные параметры, реализация повторного использования параметровCurryingодно из основных применений.
вышесказанноеincrement
, addTen
является примером повторного использования параметра. правильноadd
После того, как метод зафиксирует первый параметр равным 10, метод становится методом, который добавляет 10 к принятому значению переменной.
отложенное исполнение
Отложенное выполнение такжеCurryingВажным сценарием использования являются те же функции привязки и стрелки, которые также могут выполнять ту же функцию.
В интерфейсной разработке распространенным сценарием является привязка события onClick к метке и рассмотрение возможности передачи параметров для связанного метода.
Вот несколько распространенных методов сравнения плюсов и минусов:
-
через атрибут данных
<div data-name="name" onClick={handleOnClick} />
Через атрибут data сущность можно передать тольконитьданные, если вам нужно передать сложные объекты, вы можете передать только
JSON.stringify(data)
для передачи данных, которые соответствуют формату объекта JSON, но не могут поддерживать более сложные объекты. (Хотя большую часть времени тоже нет необходимости передавать сложные объекты) -
через метод привязки
<div onClick={handleOnClick.bind(null, data)} />
метод привязки и вышеописанное реализовано
currying
Методы очень похожи по функциям и почти одинаковы по реализации. Единственная разница может заключаться в том, что метод привязки должен принудительно задавать контекст привязки, то есть первый параметр привязки будет использоваться как точка this исходной функции при ее запуске. иcurrying
Этот параметр не является обязательным. так что используйтеcurrying
Или привязка - это просто вопрос компромиссов. -
стрелочная функция
<div onClick={() => handleOnClick(data))} />
Стрелочные функции могут реализовывать отложенное выполнение и не должны указывать контекст, как методы связывания. Возможно, единственная проблема заключается в том, что в React некоторые люди возражают против написания стрелочных функций в тегах jsx, что может легко привести к написанию бизнес-логики непосредственно в тегах jsx.
-
карри
<div onClick={currying(handleOnClick, data)} />
Сравнение производительности
пройти черезjsPerf
Производительность четырех методов была проверена, и результаты были следующими:箭头函数
>bind
>currying
>trueCurrying
.
По сравнению с функцией привязки функция каррирования в принципе аналогична, но имеет огромную разницу в производительности, поскольку привязка реализуется браузером, а эффективность работы повышается.
Из этого результатаCurryingПроизводительность несомненно худшая, но с другой стороны даже худшаяtrueCurrying
Он также может достигать 50 Вт операций в секунду на моем персональном компьютере, что указывает на то, что об этих характеристиках не нужно беспокоиться.
иtrueCurrying
метод реализован автоматическиCurryingОн недоступен в трех других методах.
Вам нужен карри?
Зачем нужен каррирование
-
Для повторного использования функции с несколькими аргументами
CurryingЧто бросается в глаза, так это то, что люди чувствуют, что функции могут быть повторно использованы таким образом.
С помощью одной строки кода,
add
Функции транслируются в increment, addTen и т. д.заCurryingСложная реализация с Lodash в качестве столбца обеспечивает
placeholder
волшебная операция. Пошутите над повторным использованием многопараметрических функций.import _ from 'loadsh' function abc (a, b, c) { return [a, b, c]; } var curried = _.curry(abc) // Curried with placeholders. curried(1)(_, 3)(2) // => [1, 2, 3]
-
Создан для функционального программирования
CurryingЭто нечто, созданное для функциональности. Происходит целый набор вещей функционального программирования,
纯函数
,compose
,container
и так далее. (Удобочитаемый"В основном адекватный гид")если вы хотите написатьPointfree Javascriptкод стиля, то без каррирования не обойтись.
Чтобы использовать compose, чтобы использовать такие вещи, как контейнеры, нам также нужна Currying.
Почему вам не нужен каррирование
-
CurryingНекоторые функции имеют другие решения
Если мы просто хотим заранее связать параметры, то у нас есть несколько готовых вариантов, связывание, стрелочные функции и т. д., и они работают лучше, чем Curring.
-
CurryingЗастрял в функциональном программировании
В этой статье
trueCurrying
реализации, что также является наиболееCurryingОн также предоставляет «новые» функции, которых нет у связывания, функций стрелок и т. д. — устойчивое каррирование (это слово придумал я).Но применение этой «новинки» не так широко распространено, как предполагалось.
Причина этого в том, что Currying является продуктом функционального программирования, он родился из функционального программирования и служит функциональному программированию.
И JavaScript не является настоящим функциональным языком программирования.По сравнению с функциональными языками программирования, такими как Haskell, JavaScript используетCurryingРавные функциональные возможности несут дополнительную нагрузку на производительность, а также не имеют вывода типа.
В результате меньше проектов, которые пишут код JavaScript, соответствующий идеям и спецификациям функционального программирования, что также ограничивает количество проектов.Curryingи другие методы обычно используются в коде JavaScript.
Если мы не готовы писать код спецификации функционального программирования и нам нужно привязать параметры только один раз заранее в коде JSX, тогда достаточно функций привязки или стрелок.
в заключении
- CurryingЭто «низкая производительность» в JavaScript, но в большинстве сценариев эта производительность незначительна.
- CurryingИдея значительно помогает улучшить возможность повторного использования функций.
- CurryingРодился в функциональном программировании и застрял в функциональном программировании. Если вы не готовы писать чистый функциональный код, есть лучшие альтернативы каррированию.
- Функциональное программирование и его идеи — это то, что нужно смотреть, изучать и применять. Итак, в конце статьи JavaScript-программисты Amway снова читают эту книгу —"В основном адекватный гид"