Los orígenes curreros y el nombre del matemático Haskell Curry (el lenguaje de programación Haskell también lleva el nombre de él).
El curry también generalmente se llama evaluación parcial. Su significado es pasar los parámetros a una función paso a paso. Después de que se pasa cada parámetro, aplique parcialmente los parámetros y devuelva una función más específica para aceptar los parámetros restantes. Múltiples capas de tales funciones de parámetros parciales pueden anidarse en el medio hasta que se devuelve el resultado final.
Por lo tanto, el proceso de currería es un proceso de aprobación gradualmente de parámetros, reduciendo gradualmente el alcance de la aplicación de funciones y resolverlas gradualmente.
Curando una función de suma
Después de la evaluación paso a paso, veamos un ejemplo simple
var concat3words = function (a, b, c) {return a+b+c; }; var concat3wordScurrying = function (a) {function de retorno (b) {función de retorno (c) {return a+b+c; }; }; }; console.log (concat3words ("foo", "bar", "baza")); // Foo Bar Baza Console.log (concat3wordScurrying ("foo")); // [function] console.log (concat3wordScurrying ("foo") ("bar") ("baza")); // Foo Bar BazaComo puede ver, Concat3WordScurrying ("foo") es una función, cada llamada devuelve una nueva función, que acepta otra llamada, y luego devuelve una nueva función hasta que finalmente se devuelve el resultado, y la distribución se resuelve, y progresa capa por capa. (PD: Las características de los cierres se aprovechan aquí)
Así que ahora vamos más allá. Si requerimos que se pasen más de 3 parámetros, ¿podemos pasar tantos parámetros como sea posible y generar el resultado cuando los parámetros no se pasan?
Primero, tengamos una implementación normal:
var add = function (elementos) {returnems.reduce (function (a, b) {return a+b}); }; console.log (add ([1,2,3,4]));Pero si pide multiplicar cada número por 10 y luego agréguelo, entonces:
var add = function (elementos, multi) {return items.map (function (elemento) {return item*multi;}). Reduce (función (a, b) {return a + b}); }; console.log (agregar ([1, 2, 3, 4], 10));Afortunadamente, hay mapas y reducen funciones. Si seguimos este patrón, necesitamos agregar 1 a cada elemento y resumirlo, entonces necesitamos reemplazar las funciones en el mapa.
Echemos un vistazo a la implementación de la curryización:
var adder = function () {var _args = []; function de return () {if (arguments.length === 0) {return _args.reduce (function (a, b) {return a + b;}); } [] .push.apply (_args, [] .slice.call (argumentos)); Return Arguments.callee; }}; var sum = adder (); console.log (suma); // suma de función (100,200) (300); // El formato de llamada es flexible, uno o más parámetros se pueden ingresar a la vez, y admite la llamada de cadena a suma (400); console.log (sum ()); // 1000 (cálculo total)El sumador anterior es una función en forma de curry, que devuelve una nueva función, y la nueva función puede aceptar nuevos parámetros en lotes, retrasando hasta el último cálculo.
Función de curry general
Un curry más típico encapsulará el último cálculo en una función y luego pasará esta función como un parámetro en la función de currying, que es clara y flexible.
Por ejemplo, multiplicar cada término por 10, podemos pasar la función de procesamiento como parámetro:
var currying = function (fn) {var _args = []; function de return () {if (arguments.length === 0) {return fn.apply (this, _args); } Array.prototype.push.apply (_args, [] .slice.call (argumentos)); Return Arguments.callee; }}; var multi = function () {var total = 0; para (var i = 0, c; c = argumentos [i ++];) {total+= c; } retorno total; }; var sum = currying (multi); suma (100,200) (300); suma (400); console.log (sum ()); // 1000 (solo se calcula cuando las llamadas en blanco)De esta manera, suma = currying (multi), la llamada es muy clara y el efecto de uso también es brillante. Por ejemplo, para acumular múltiples valores, puede usar múltiples valores como parámetros suma (1,2,3), o llamadas de cadena de soporte, suma (1) (2) (3)
La base del curry
El código anterior es en realidad una función de alto orden. Una función de alto orden se refiere a una función que opera una función. Recibe una o más funciones como parámetros y devuelve una nueva función. Además, las características del cierre también se basan para guardar los parámetros ingresados en el proceso intermedio. Ahora mismo:
Las funciones se pueden pasar como parámetros
Las funciones se pueden usar como valor de retorno de la función
Cierre
El papel de la curridulación
Cálculo de retraso. El ejemplo anterior es relativamente bajo.
Multiplexación de parámetros. Cuando la misma función se llama varias veces y los parámetros pasados son en su mayoría los mismos, entonces la función puede ser un buen candidato para el curry.
Crear funciones dinámicamente. Esto se puede generar dinámicamente después de los resultados del cálculo parcial, sobre esta base, se genera dinámicamente una función para procesar el negocio posterior, omitiendo así los cálculos repetidos. O puede crear dinámicamente una nueva función aplicando parte del subconjunto de parámetros que se transmitirán a la función de llamada, que guarda los parámetros pasados repetidamente (no necesariamente cada vez en el futuro). Por ejemplo, un método auxiliar para los navegadores de eventos para agregar eventos:
var addEvent = function (el, type, fn, captura) {if (window.addeventListener) {el.AdDeventListener (type, function (e) {fn.call (el, e);}, captura); } else if (window.attachevent) {el.attachevent ("on" + type, function (e) {fn.call (el, e);}); }};Cada vez que agrega un evento, debe ejecutar si ... de lo contrario ... de hecho, en un navegador, solo necesita tomar una decisión una vez. Puede generar dinámicamente una nueva función basada en el resultado después de un juicio, y no hay necesidad de recalcularla en el futuro.
var addEvent = (function () {if (window.adDeventListener) {return Function (el, stype, fn, capture) {el.adDeventListener (stype, function (e) {fn.call (el, e);}, (captura);};} más if (window.attachEvent) {function return (el, stype, fn, fn) { el.attachevent ("en" + stype, function (e) {fn.call (el, e);});Este ejemplo, después del primer juicio de if ... else ..., se completa parte del cálculo, y se crea una nueva función dinámicamente para procesar los parámetros pasados más tarde. Esta es una currilación típica.
El método funct.prototype.bind también es una aplicación de curry
A diferencia del método de llamada/aplicación que se ejecuta directamente, el método de enlace establece el primer parámetro en el contexto de la ejecución de funciones, y otros parámetros se pasan al método de llamada a su vez (el cuerpo de la función en sí no se ejecuta, que puede considerarse como una ejecución retrasada), y crea y devuelve dinámicamente una nueva función, que se ajusta a las características de la curria.
var foo = {x: 888}; var bar = function () {console.log (this.x); } .bind (foo); // Barra de enlace (); // 888A continuación se muestra una simulación de una función de enlace. TestBind crea y devuelve una nueva función. En la nueva función, la función que realmente quiere ejecutar el negocio está vinculado al contexto aprobado en el parámetro real, y la ejecución se retrasa.
Function.prototype.testbind = function (alcance) {var fn = this; //// Esto apunta a una función que llama al método testbind, return function () {return fn.apply (alcance); }}; var testBindBar = bar.testbind (foo); // unir foo para retrasar la ejecución de console.log (testBindBar); // función (ver, después del enlace, devolver una nueva función que retrasa la ejecución) testBindBar (); // 888Aquí debemos prestar atención a la comprensión de esto en prototipo.
El análisis anterior del artículo en profundidad de las funciones currying en JavaScript Currying es todo el contenido que comparto con usted. Espero que pueda darle una referencia y espero que pueda apoyar más a Wulin.com.