Heim >Web-Frontend >js-Tutorial >Anti-Currying in JS

Anti-Currying in JS

大家讲道理
大家讲道理Original
2017-08-19 10:33:481705Durchsuche

Anti-Currying

Im Gegenteil besteht die Rolle von Anti-Currying darin, die Anwendbarkeit von Funktionen zu erweitern, sodass Funktionen, die ursprünglich Funktionen sind, die einem bestimmten Objekt gehören, möglich sind Wird von jedem Objekt verwendet. Das verwendete .
dient dazu, die unten angegebene Funktionssignatur


obj.func(arg1, arg2)


in eine Funktion umzuwandeln Formular mit folgender Signatur:


func(obj, arg1, arg2)


Dies ist die formale Beschreibung des Decurrying.

Zum Beispiel eine einfache Implementierung des Folgenden:


Function.prototype.uncurrying = function() {    var that = this;    return function() {        return Function.prototype.call.apply(that, arguments);
    }
};function sayHi () {    return "Hello " + this.value +" "+[].slice.call(arguments);
}var sayHiuncurrying=sayHi.uncurrying();
console.log(sayHiuncurrying({value:'world'},"hahaha"));


Erklärung:

  • uncurrying ist eine Methode, die im Prototyp von Function definiert ist, sodass diese Methode für alle Funktionen verwendet werden kann. Beim Aufruf: sayHiuncurrying=sayHi.uncurrying(), also zeigt dies in uncurrying auf die sayHi-Funktion (im Allgemeinen zeigt dies in der Prototyp-Methode nicht auf den Prototyp-Objekt-Prototyp, sondern auf das aufrufende Objekt, wobei das aufrufende Objekt ein anderes ist Funktion. Funktionen sind auch Objekte in Javascript)

  • call.apply(that, arguments) Legen Sie dies als Kontext der Aufrufmethode fest und übergeben Sie dann Argumente an Die Aufrufmethode zeigt im vorherigen Beispiel tatsächlich auf sayHi, sodass der Aufruf von sayHiuncurrying(arg1, arg2, ...) äquivalent zu sayHi.call(arg1, arg2, ...);

  • sayHi. Aufruf (arg1, arg2, ...), die Aufruffunktion behandelt arg1 als Kontext von sayHi und übergibt dann die verbleibenden Parameter wie arg2, ... an sayHi, also ist das endgültige Äquivalent arg1.sayHi(arg2,...) ;

  • Das ist also äquivalent zu sayHiuncurrying(obj,args) gleich obj.sayHi(args).

Schließlich betrachten wir es umgekehrt. Tatsächlich ist Anti-Currying gleichbedeutend mit der Umwandlung der ursprünglichen Form von sayHi(args) in sayHiuncurrying(obj,args). der Anwendungsbereich von sayHi Generalized. Abstrakter ausgedrückt ermöglicht Uncurrying Anti-Currying die Umwandlung des ursprünglichen x.y(z)-Aufrufs in einen Aufruf in der Form y(x',z). Angenommen, x' ist x oder ein anderes Objekt, erweitert dies den Anwendungsbereich der Funktion.

Universelle Decurrying-Funktion

Im obigen Beispiel ist Uncurrying in den Prototyp geschrieben, was nicht gut ist. Wir können Uncurrying tatsächlich in eine separate Funktion kapseln; >


var uncurrying= function (fn) {    return function () {        var args=[].slice.call(arguments,1);        return fn.apply(arguments[0],args);        
    }    
};
Die obige Funktion ist sehr klar und unkompliziert.

Bei Verwendung wird uncurrying aufgerufen und eine vorhandene Funktion fn übergeben. Die decurrying-Funktion gibt eine neue Funktion zurück. Der erste von der neuen Funktion akzeptierte Parameter wird an den Kontext dieser Funktion in fn gebunden Als Argument an fn übergeben.

Eine populärere Erklärung für Anti-Currying kann also das Ausleihen von Funktionen sein, was bedeutet, dass Funktionen andere Objekte akzeptieren und verarbeiten und durch Ausleihen verallgemeinern können, um den Anwendungsbereich der Funktion zu erweitern.


Uncurrying wird also häufiger verwendet, um andere in Javascript integrierte Methoden auszuleihen, ohne sie alle selbst implementieren zu müssen.

Die Textbeschreibung ist etwas kompliziert, also schauen wir uns den Code weiter an:


var test="a,b,c";
console.log(test.split(","));var split=uncurrying(String.prototype.split);   //[ 'a', 'b', 'c' ]console.log(split(test,','));                   //[ 'a', 'b', 'c' ]
split =uncurrying(String.prototype.split) Übergeben Sie einen bestimmten fn an uncurrying, d. h. String.prototype.split. Die Split-Funktion hat die Funktion String.prototype.split. ), der erste übergebene Parameter ist der Kontext der geteilten Ausführung, und die übrigen Parameter entsprechen der Übergabe an die ursprüngliche String.prototype.split-Funktion.


Sehen Sie sich ein anderes Beispiel an:


var $ = {};
console.log($.push);                          // undefinedvar pushUncurrying = uncurrying(Array.prototype.push);
$.push = function (obj) {
    pushUncurrying(this,obj);
};
$.push('first');
console.log($.length);                        // 1console.log($[0]);                            // firstconsole.log($.hasOwnProperty('length'));      // true
Dies imitiert eine „ähnliche

jqueryLibrary“ leiht sich bei der Implementierung die Push-Methode von Array aus. Wir wissen, dass Objekte keine Push-Methode haben, daher gibt console.log(obj.push) ein undefiniertes Array zurück. Die native Array-Methode (JS-Engine) behält das Längenattribut
des Pseudo-Arrays bei. Array-Objekt

und Array-Mitglieder.

Aus dem gleichen Grund können wir weiterhin:


Zum Beispiel implementieren wir Unsere eigene Klasse Wenn Sie eine Bibliothek verwenden und einige Methoden den nativen ähneln, können Sie die nativen Methoden durch Uncurrying ausleihen.
var indexof=uncurrying(Array.prototype.indexOf);
$.indexOf = function (obj) {    return indexof(this,obj);
};
$.push("second");
console.log($.indexOf('first'));              // 0console.log($.indexOf('second'));             // 1console.log($.indexOf('third'));              // -1

Wir können auch die Methode Function.prototype.call/apply entsperren, zum Beispiel:


Auf diese Weise können Funktionen sehr flexibel als gewöhnliche „Daten“ verwendet werden, was der funktionalen Programmierung ähnelt. Diese Verwendung ist häufig in einigen Klassenbibliotheken zu sehen.
var call= uncurrying(Function.prototype.call);var fn= function (str) {
    console.log(this.value+str);
};var obj={value:"Foo "};
call(fn, obj,"Bar!");                       // Foo Bar!

Der Angriff der allgemeinen Uncurrying-Funktion

Die obige Uncurrying-Funktion ist eine Version, die eher den Denkgewohnheiten entspricht und leicht zu verstehen ist. Als nächstes werden wir den gesamten Weg angreifen in mehreren anderen Versionen:

Erstens: Wenn das B-Raster höher ist, kann Uncurrying auch so geschrieben werden:

Wenn Sie das B-Raster natürlich noch verbessern müssen, können Sie dies natürlich immer noch tun. Es kann so sein:

var uncurrying= function (fn) {    return function () {        var context=[].shift.call(arguments);        return fn.apply(context,arguments);
    }
};


Das obige ist der detaillierte Inhalt vonAnti-Currying in JS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn