Currying -Ursprünge und der Name des Mathematikers Haskell Curry (die Programmiersprache Haskell ist auch nach ihm benannt).
Currying wird normalerweise auch als teilweise Bewertung bezeichnet. Seine Bedeutung ist es, die Parameter Schritt für Schritt an einen Funktion zu übergeben. Nachdem jeder Parameter übergeben wurde, wenden Sie teilweise Parameter an und geben Sie eine spezifischere Funktion zurück, um die verbleibenden Parameter zu akzeptieren. Mehrere Schichten solcher Teilparameterfunktionen können in der Mitte verschachtelt werden, bis das Endergebnis zurückgegeben wird.
Daher ist der Currying -Prozess ein Prozess des allmählichen Übergebens von Parametern, allmählich verengt den Anwendungsbereich der Funktionen und die allmähliche Lösung.
Currying einer Summenfunktion
Schauen wir uns ein einfaches Beispiel an
var concat3words = Funktion (a, b, c) {return a+b+c; }; var concat3WordScurrying = Funktion (a) {return function (b) {return function (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 BazaWie Sie sehen können, ist concat3WordScurrying ("foo") eine Funktion, jeder Aufruf gibt eine neue Funktion zurück, die einen anderen Aufruf akzeptiert, und dann eine neue Funktion zurückgibt, bis das Ergebnis schließlich zurückgegeben wird, und die Verteilung gelöst wird und schicht für Schicht voranschreitet. (PS: Die Eigenschaften von Schließungen werden hier ausgenutzt)
Also gehen wir jetzt weiter. Wenn wir mehr als 3 Parameter übergeben werden müssen, können wir so viele Parameter wie möglich übergeben und das Ergebnis ausgeben, wenn die Parameter nicht übergeben werden?
Lassen Sie uns zunächst eine normale Implementierung haben:
var add = function (items) {return items.Reduce (Funktion (a, b) {return a+b}); }; console.log (add ([1,2,3,4]);Wenn Sie jedoch fragen, jede Nummer mit 10 zu multiplizieren und dann hinzuzufügen, dann:
var add = function (items, multi) {return items.map (function (item) {return item*multi;}). Reduzieren (Funktion (a, b) {return a + b}); }; console.log (add ([1, 2, 3, 4], 10));Glücklicherweise gibt es Karten- und Reduzierungsfunktionen. Wenn wir diesem Muster folgen, müssen wir jedem Element 1 hinzufügen und zusammenfassen, dann müssen wir die Funktionen in der Karte ersetzen.
Schauen wir uns die Curryisierungsimplementierung an:
var adder = function () {var _args = []; return function () {if (Argumente.length === 0) {return _args.ReDuce (Funktion (a, b) {return a + b;}); } [] .push.apply (_args, [] .slice.call (Argumente)); Return Argumente.Callee; }}; var sum = adder (); console.log (sum); // Funktionsumme (100.200) (300); // Das Anrufformat ist flexibel, eine oder mehrere Parameter können gleichzeitig eingegeben werden, und es unterstützt die Kettenaufruf auf Summe (400). console.log (sum ()); // 1000 (Gesamtberechnung)Der obige Addierer ist eine Curry-förmige Funktion, die eine neue Funktion zurückgibt, und die neue Funktion kann neue Parameter in Stapeln akzeptieren und sich bis zur letzten Berechnung verzögern.
General Curry -Funktion
Ein typischeres Currying umfasst die letzte Berechnung in eine Funktion und übergibt diese Funktion dann als Parameter in die Currying -Funktion, die klar und flexibel ist.
Multiplizieren Sie beispielsweise jeden Term mit 10, wir können die Verarbeitungsfunktion als Parameter übergeben:
var currying = function (fn) {var _args = []; return function () {if (Argumente.length === 0) {return fn.apply (this, _args); } Array.prototype.push.apply (_args, [] .slice.call (Argumente)); Return Argumente.Callee; }}; var multi = function () {var total = 0; für (var i = 0, c; c = Argumente [i ++];) {total+= c; } Return Total; }; var sum = currying (multi); Summe (100.200) (300); Summe (400); console.log (sum ()); // 1000 (es wird nur berechnet, wenn leere Anrufe aufrufen)Auf diese Weise ist SUM = Currying (Multi), der Anruf ist sehr klar und der Gebrauchseffekt ist auch brillant. Um beispielsweise mehrere Werte zu akkumulieren, können Sie mehrere Werte als Parametersum (1,2,3) verwenden oder Kettenaufrufe, Summe (1) (2) (3), unterstützen oder Kettenaufrufe unterstützen.
Die Grundlage des Currying
Der obige Code ist tatsächlich eine Funktion mit hoher Ordnung. Eine Funktion hoher Ordnung bezieht sich auf eine Funktion, die eine Funktion betreibt. Es empfängt eine oder mehrere Funktionen als Parameter und gibt eine neue Funktion zurück. Darüber hinaus werden die Merkmale des Verschlusses auch stützt, um die im Zwischenprozess eingegebenen Parameter zu speichern. Im Augenblick:
Funktionen können als Parameter übergeben werden
Funktionen können als Rückgabewert der Funktion verwendet werden
Schließung
Die Rolle der Currykulation
Verzögerungsberechnung. Das obige Beispiel ist relativ niedrig.
Parameter Multiplexing. Wenn dieselbe Funktion mehrmals aufgerufen wird und die übergebenen Parameter meist die gleichen sind, kann die Funktion ein guter Kandidat für das Currying sein.
Funktionen dynamisch erstellen. Dies kann dynamisch nach partiellen Berechnungsergebnissen generiert werden. Auf dieser Grundlage wird eine neue Funktion dynamisch generiert, um das nachfolgende Geschäft zu verarbeiten, wodurch wiederholte Berechnungen weggelassen werden. Oder Sie können eine neue Funktion dynamisch erstellen, indem Sie einen Teil der Teilmenge der Parameter anwenden, die in die Aufruffunktion übergeben werden sollen, wodurch die Parameter wiederholt gespeichert werden (nicht unbedingt jedes Mal in der Zukunft). Zum Beispiel eine Hilfsmethode für Ereignisbrowser zum Hinzufügen von Ereignissen:
var addEvent = function (el, type, fn, capture) {if (window.addeventListener) {el.addeventListener (Typ, Funktion (e) {fn.call (el, e);}, capture); } else if (window.attachEvent) {El.AttACHEvent ("on" + Typ, Funktion (e) {fn.call (el, e);}); }};Jedes Mal, wenn Sie eine Veranstaltung hinzufügen, müssen Sie ausführen, wenn ... sonst ... tatsächlich in einem Browser Sie nur einmal eine Entscheidung treffen müssen. Sie können nach einem Urteil dynamisch eine neue Funktion basierend auf dem Ergebnis erzeugen, und es besteht keine Notwendigkeit, sie in Zukunft neu zu berechnen.
var addEvent = (function(){ if (window.addEventListener) { return function(el, sType, fn, capture) { el.addEventListener(sType, function(e) { fn.call(el, e); }, (capture)); }; } else if (window.attachEvent) { return function(el, sType, fn, capture) { attachEvent ("on" + stype, function (e) {fn.call (el, e);});In diesem Beispiel wird nach dem ersten Urteil von if ... sonst ... ein Teil der Berechnung abgeschlossen, und eine neue Funktion wird dynamisch erstellt, um die später übergebenen Parameter zu verarbeiten. Dies ist eine typische Currylierung.
Die Methode der Funktion.Prototype.bind ist auch eine Curry -Anwendung
Im Gegensatz zu der direkten Aufruf/Anwendung, die direkt ausgeführt wird, legt die Bind -Methode den ersten Parameter in den Kontext der Funktionsausführung fest, und andere Parameter werden wiederum an die aufrufende Methode übergeben (der Körper der Funktion selbst wird nicht ausgeführt, was als verzögerte Ausführung angesehen werden kann) und erstellt und gibt dynamisch eine neue Funktion zurück, die den Currying -Eigenschaften entspricht.
var foo = {x: 888}; var bar = function () {console.log (this.x); } .bind (foo); // bar () binden; // 888Unten ist eine Simulation einer Bindungsfunktion. Testbind erstellt und gibt eine neue Funktion zurück. In der neuen Funktion ist die Funktion, die das Geschäft wirklich ausführen möchte, an den im tatsächlichen Parameter übergebenen Kontext und die Ausführung verzögert.
Function.prototype.Testbind = Funktion (Bereich) {var fn = this; //// Dies weist auf eine Funktion hin, die die Testbind -Methode aufruft, return function () {return fn.apply (Scope); }}; var testbindbar = bar.testbind (foo); // Foo binden, um die Ausführung von console.log (testbindbar) zu verzögern; // Funktion (siehe nach Bind, geben Sie eine neue Funktion zurück, die die Ausführung verzögert) testbindbar (); // 888Hier sollten wir auf das Verständnis des Prototyps achten.
Die obige Artikel-Tief-Analyse der Funktionen, die das Currying in JavaScript Currying Currying ist, ist der gesamte Inhalt, den ich mit Ihnen teile. Ich hoffe, Sie können Ihnen eine Referenz geben und ich hoffe, Sie können wulin.com mehr unterstützen.