Verwandte Empfehlungen: Javascript-Tutorial
apply(context,[arguments])
, call(context,param1,param2,...)
.Currying ist eine Technik, die eine Funktion, die mehrere Parameter akzeptiert, in eine Funktion umwandelt, die einen einzelnen Parameter akzeptiert (den ersten Parameter der ursprünglichen Funktion), und eine neue Funktion zurückgibt, die die verbleibenden Parameter akzeptiert und ein Ergebnis zurückgibt.
Hier ist zum Beispiel eine add()
-Funktion, eine Funktion, die zum Verarbeiten der Addition und Summe der Parameter (param1, params2,...) verwendet wird, die wir an sie übergeben.
// Hier ist die erste Funktion „add(x, y)“ mit zwei Parametern „x“, „y“ function add(x, y){ gib x + y zurück; } // Rufen Sie die Funktion „add()“ auf und geben Sie zwei Parameter „4“ und „6“ an add(4,6); // Computerbetrieb simulieren, im ersten Schritt den ersten Parameter 4 übergeben Funktion add(4, y){ return 4 + y; } // Computerbetrieb simulieren, im zweiten Schritt den ersten Parameter 6 übergeben Funktion add(4, 6){ Rückgabe 4 + 6; }
Wie würde es aussehen, wenn wir die Funktion add()
ausführen würden? Hier ist eine einfache Implementierung:
// Die Curry-Funktion add() kann einige Parameter akzeptieren. function add(x,y){ if (typeof y === 'undefiniert') { Rückgabefunktion (neu){ return x + newy; } } // Vollständige Anwendungsrückgabe x + y; } // Testaufrufe console.log(typeof add(4)); // [Funktion] console.log(add(4)(6)); // 10 // Sie können eine Speicherfunktion erstellen let saveAdd = add(4); console.log(saveAdd(6)); // 10
Wie aus der obigen einfachen Curry-Funktion add()
ersichtlich ist, kann die Funktion einige Funktionen akzeptieren und dann eine neue Funktion zurückgeben, um mit der Verarbeitung der verbleibenden Funktionen fortzufahren.
Hier erstellen wir eine öffentliche Currying-Funktion, damit wir nicht jedes Mal, wenn wir eine Funktion schreiben, den darin enthaltenen komplexen Currying-Prozess implementieren müssen.
//Definieren Sie eine createCurry-Funktion function createCurry(fn){ var Slice = Array.prototype.slice, gespeicherte_args = Slice.call(arguments,1); Rückgabefunktion () { let new_args = Slice.call(Argumente), args = gespeicherte_args.concat(new_args); return fn.apply(null,args); }}
In der obigen öffentlichen Currying-Funktion:
arguments
handelt es sich nicht um ein echtes Array, sondern um ein Objekt mit einem length
. Daher leihen wir uns die slice
-Methode von Array.prototype
aus, um uns bei der Konvertierung arguments
in ein echtes Array zu helfen und unsere Operation zu erleichtern.createCurry
zum ersten Mal aufrufen, enthält die Variable stored_args
die Parameter mit Ausnahme des ersten Parameters, da der erste Parameter die Funktion ist, die wir zum Curry benötigen.createCurry
zurückgegebene Funktion ausführen, ruft die Variable new_args
die Parameter ab und konvertiert sie in ein Array.stored_args
gespeicherten Wert zu, führt den Wert der Variablen new_args
in einem neuen Array zusammen und weist ihn der Variablen args
zu.fn.apply(null,args)
aufgerufen, um die Curry-Funktion auszuführen.Jetzt testen wir die öffentliche Curry-Funktion
// gewöhnliche Funktion add() Funktion add(x, y){ gib x + y zurück; } // Curry, um eine neue Funktion zu erhalten var newAdd = createCurry(add,4); console.log(newAdd(6)); // 10 //Eine weitere einfache Möglichkeit console.log(createCurry(add,4)(6));// 10
Natürlich ist dies nicht auf das Currying von zwei Parametern beschränkt, sondern auch auf mehrere Parameter:
// Mehrere Parameter Die gewöhnliche Funktion function add (a,b,c,d){ gib a + b + c + d zurück; } // Curry die Funktion, um eine neue Funktion zu erhalten, mehrere Parameter können nach Belieben geteilt werden console.log(createCurry(add,4,5)(5,6)); // Zweistufiges Curry let add_one = createCurry(add,5); console.log(add_one(5,5,5));// 20 let add_two = createCurry(add_one,4,6); console.log(add_two(6)); // 21Durch
das obige Beispiel können wir eine Einschränkung finden, das heißt, ob es sich um zwei Parameter oder mehrere Parameter handelt, es kann nur in zwei Schritten ausgeführt werden, wie zum Beispiel der folgenden Formel:
wenn wir flexibler sein wollen:
Wie implementieren wir es?
. Nach den obigen Übungen haben wir festgestellt, dass die von uns erstellte Curry-Funktion bestimmte Einschränkungen aufweist. Wir hoffen, dass die Funktion in mehreren Schritten ausgeführt werden kann:
// Erstellen Sie eine Curry-Funktion, die in mehreren Schritten ausgeführt werden kann , führen Sie es aus, wenn die Anzahl der Parameter erreicht ist: // Funktionsformel: fn(x,y,z,w) ==> fn(x)(y)(z)(w); let createCurry = (fn,...params)=> { let args = parsms ||. let fnLen = fn.length; // Geben Sie die Parameterlänge der Curry-Funktion an return (...res)=> { // Alle vorherigen Parameter über die Bereichskette abrufen let allArgs = args.slice(0); // Kopieren Sie die von Schließungen gemeinsam genutzten args-Parameter tief, um die Auswirkungen nachfolgender Vorgänge zu vermeiden (Referenztyp). allArgs.push(...res); if(allArgs.length < fnLen){ // Wenn die Anzahl der Parameter kleiner als die Parameterlänge der ursprünglichen Funktion ist, rufen Sie die Funktion createCurry rekursiv auf. return createCurry.call(this,fn,...allArgs); }anders{ // Wenn die Anzahl der Parameter erreicht ist, Funktionsausführung auslösen return fn.apply(this,allArgs); } } } // Gewöhnliche Funktion function add(a,b,c,d){ mit mehreren Parametern gib a + b + c + d zurück; } //Testen Sie die Currying-Funktion let curryAdd = createCurry(add,1); console.log(curryAdd(2)(3)(4)); //
Wir haben seit mehr als 10 Jahren flexible Currying-Funktionen implementiert, aber hier finden wir ein weiteres Problem:
curryAdd(add,1,2,3,4)()
;add()
aufgerufen wird. Dies ist auch eine Möglichkeit. Da wir hier jedoch die Anzahl der Parameter erfüllen, müssen wir uns immer noch mit dieser Situation befassen.Hier müssen wir nur ein Urteil fällen, bevor wir die Funktion zurückgeben:
let createCurry = (fn,...params)=> { let args = parsms ||. let fnLen = fn.length; // Geben Sie die Parameterlänge der Curry-Funktion an if(length === _args.length){ // Beurteilung hinzufügen. Wenn die Anzahl der Parameter zum ersten Mal ausreicht, rufen Sie die Funktion direkt auf, um das Ergebnis zu erhalten return fn.apply(this,args); } return (...res)=> { let allArgs = args.slice(0); allArgs.push(...res); if(allArgs.length < fnLen){ return createCurry.call(this,fn,...allArgs); }anders{ return fn.apply(this,allArgs); } }}
Das Obige kann als flexible Curry-Funktion betrachtet werden, ist hier jedoch nicht sehr flexibel, da wir nicht steuern können, wann es ausgeführt wird. Solange die Anzahl der Parameter ausreicht, wird es automatisch ausgeführt. Was sollten wir tun, wenn wir einen Zeitpunkt erreichen wollen, der die Ausführung steuern kann?
Lassen Sie uns die Funktionsformel hier direkt erklären:
// Wenn die Parameter erfüllt sind, rufen Sie die Funktion auf let createCurry = (fn,...params)=> { let args = parsms ||. let fnLen = fn.length; // Geben Sie die Parameterlänge der Curry-Funktion an //Natürlich muss das Urteil hier auskommentiert werden, sonst wird das Ergebnis direkt ausgeführt, wenn die Anzahl der Parameter zum ersten Mal ausreicht //if(length === _args.length){ // Beurteilung hinzufügen. Wenn die Anzahl der Parameter zum ersten Mal ausreicht, rufen Sie die Funktion direkt auf, um das Ergebnis zu erhalten //return fn.apply(this,args); //} return (...res)=> { let allArgs = args.slice(0); allArgs.push(...res); // Hier wird beurteilt, ob die Eingabeparameter größer als 0 sind. Wenn es größer als 0 ist, wird beurteilt, ob die Anzahl der Parameter ausreichend ist. // && kann hier nicht verwendet werden. Wenn && verwendet wird, wird das Ergebnis ausgeführt, wenn die Anzahl der Parameter ausreicht. if(res.length > 0 || allArgs.length < fnLen){ return createCurry.call(this,fn,...allArgs); }anders{ return fn.apply(this,allArgs); } } } // Gewöhnliche Funktion function add(a,b,c,d){ mit mehreren Parametern gib a + b + c + d zurück; } // Testen Sie die steuerbare Currying-Funktion let curryAdd = createCurry(add,1); console.log(curryAdd(2)(3)(4)); // Funktion console.log(curryAdd(2)(3)(4)()); // 10 console.log(curryAdd(2)(3)()); Gibt NaN zurück, wenn die Parameter nicht ausreichen.
Weitere Informationen finden Sie
im JavaScript-Lern-Tutorial.
Bitte achten Sie auf PHP. Weitere verwandte Artikel auf der chinesischen Website!