Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung der Funktionsrationalisierung in JavaScript

Detaillierte Erläuterung der Funktionsrationalisierung in JavaScript

青灯夜游
青灯夜游nach vorne
2020-12-18 17:53:246451Durchsuche

Detaillierte Erläuterung der Funktionsrationalisierung in JavaScript

Verwandte Empfehlungen: „Javascript-Video-Tutorial

Als ich kürzlich Technologie-Blogs in der Community las, sah ich versehentlich die Wörter „Funktions-Currying“ und es gab auch eine Anforderung, „JS-Funktions-Currying“ handschriftlich zu schreiben , ich frage mich, was fortgeschrittenes Currying ist? Noch nie davon gehört? Ich habe mich mit dem Problem beschäftigt, es studiert und etwas sortiert.

Was ist Function Currying?

Was ist Function Currying? Werfen wir einen Blick darauf, wie Wikipedia erklärt:

In der Informatik bedeutet Currying (englisch: Currying), auch übersetzt als Currying oder Currying, die Umwandlung einer Funktion, die mehrere Parameter akzeptiert, in eine Funktion, die einen einzelnen Parameter akzeptiert (ursprünglich eine Funktion, die übernimmt das erste Argument einer Funktion) und gibt eine neue Funktion zurück, die die verbleibenden Argumente akzeptiert und ein Ergebnis zurückgibt.

Diese Technik wurde von Christopher Strachey nach dem Logiker Haskell Gary benannt, obwohl sie von Moses Schönfinkel und Gottlob Frege erfunden wurde.

Intuitiv heißt es beim Currying: „Wenn Sie einige Parameter festlegen, erhalten Sie eine Funktion, die die verbleibenden Parameter akzeptiert“. Wenn also für die Funktion y^x mit zwei Variablen y=2 fest ist, erhalten wir die Funktion 2^x mit einer Variablen.

Das Konzept von Currying ist eigentlich nicht kompliziert. Einfach ausgedrückt: Übergeben Sie nur einen Teil der Parameter an die Funktion, um sie aufzurufen, und lassen Sie sie eine Funktion zurückgeben, die die restlichen Parameter verarbeitet.

Wenn die Texterklärung noch etwas abstrakt ist, verwenden wir die Add-Funktion, um eine einfache Funktions-Curry-Implementierung zu erstellen.

// 普通的add函数
function add(x, y) {
    return x + y
}

// add函数柯里化后
var curryingAdd = function(x) {
  return function(y) {
    return x + y;
  };
};

// 函数复用
var increment = curryingAdd(1);
var addTen = curryingAdd(10);

increment(2);
// 3
addTen(2);
// 12
Tatsächlich werden die x- und y-Parameter der Add-Funktion dahingehend geändert, dass eine Funktion zum Empfangen von x verwendet und dann eine Funktion zum Verarbeiten des y-Parameters zurückgegeben wird. Jetzt sollte die Idee klarer sein, nämlich die Funktion aufzurufen, indem nur ein Teil der Parameter übergeben wird, und sie eine Funktion zurückgeben zu lassen, die die restlichen Parameter verarbeitet.

Warum müssen wir Curry-Funktionen verwenden?

Nachdem ich das oben Gesagte über das Currying der Add-Funktion gelesen habe, stellt sich die Frage: Was nützt es, so viel Aufwand in die Kapselung einer Ebene zu investieren?

1. Parameter-Wiederverwendung

Tatsächlich hat das erste Curry-Beispiel der Funktion „Add“ bereits die Bequemlichkeit der Funktionswiederverwendung angesprochen, die durch das Currying der Funktion „Quickly“ entsteht Um die Inkrementierungsfunktion und die AddTen-Funktion zu implementieren, schauen wir uns ein Beispiel an:
// 正常正则验证字符串 reg.test(txt)

// 函数封装后
function check(reg, txt) {
    return reg.test(txt)
}

check(/\d+/g, 'test')       //false
check(/[a-z]+/g, 'test')    //true

// Currying后
function curryingCheck(reg) {
    return function(txt) {
        return reg.test(txt)
    }
}

var hasNumber = curryingCheck(/\d+/g)
var hasLetter = curryingCheck(/[a-z]+/g)

hasNumber('test1')      // true
hasNumber('testtest')   // false
hasLetter('21212')      // false
Das obige Beispiel ist eine reguläre Überprüfung. Rufen Sie normalerweise einfach die Prüffunktion auf, aber wenn ich viele Stellen habe, um zu überprüfen, ob es tatsächlich Zahlen gibt. Der erste Parameter reg muss wiederverwendet werden, damit andere Stellen hasNumber, hasLetter und andere Funktionen direkt aufrufen können, sodass die Parameter wiederverwendet werden können und der Aufruf bequemer ist. „Zweitens, bestätigen Sie im Voraus.“ DOM-Operationen sind üblich, aber die erste Schreibweise oben ist auch relativ üblich, aber schauen wir uns die zweite Schreibweise an, die relativ häufig vorkommt. Die erste Schreibweise besteht darin, eine neue Funktion selbst auszuführen und dann zurückzugeben. was tatsächlich im Voraus bestimmt, welche Methode verwendet wird.

Vermeiden Sie jedes Mal ein Urteil

.

3. Verzögerte Berechnung/Operation
var on = function(element, event, handler) {
    if (document.addEventListener) {
        if (element && event && handler) {
            element.addEventListener(event, handler, false);
        }
    } else {
        if (element && event && handler) {
            element.attachEvent('on' + event, handler);
        }
    }
}

var on = (function() {
    if (document.addEventListener) {
        return function(element, event, handler) {
            if (element && event && handler) {
                element.addEventListener(event, handler, false);
            }
        };
    } else {
        return function(element, event, handler) {
            if (element && event && handler) {
                element.attachEvent('on' + event, handler);
            }
        };
    }
})();
Wie bind, das häufig in unserem js verwendet wird, ist der Implementierungsmechanismus Currying.

Wie implementiert man Funktions-Currying?

Allgemeine Kapselungsmethode:

var on = function(isSupport, element, event, handler) {
    isSupport = isSupport || document.addEventListener;
    if (isSupport) {
        return element.addEventListener(event, handler, false);
    } else {
        return element.attachEvent('on' + event, handler);
    }
}
Die erste ist die vorläufige Kapselung. Die vorläufigen Parameter werden durch Abschlüsse gespeichert, dann durch Abrufen der verbleibenden Argumente gespleißt und schließlich wird die Funktion ausgeführt, die Currying erfordert.
Aber die obige Funktion weist immer noch einige Mängel auf, da sie nur einen weiteren Parameter erweitern kann (Currying(a)(b)(c) wird im Allgemeinen nicht unterstützt). , diese Art von Funktion wird nicht unterstützt. In jedem Fall werden Sie darüber nachdenken, die Rekursion zu verwenden und sie eine Ebene weiter zu kapseln.
Function.prototype.bind = function (context) {
    var _this = this
    var args = Array.prototype.slice.call(arguments, 1)

    return function() {
        return _this.apply(context, args)
    }
}
Dies basiert tatsächlich auf dem vorläufigen Hinzufügen rekursiver Aufrufe. Solange die Anzahl der Parameter kleiner als die anfängliche fn.length ist, wird die Rekursion weiterhin ausgeführt.

Wie ist die Leistung beim Funktions-Currying?

Über die Leistung von Currying sollten wir die folgenden Punkte wissen:

Der Zugriff auf Argumentobjekte ist normalerweise etwas langsamer als der Zugriff auf benannte Parameter.

Einige ältere Browserversionen sind bei der Implementierung von arguments.length ziemlich langsam.

Verwenden fn.apply( … ) und fn.call( … ) sind normalerweise etwas langsamer als der direkte Aufruf von fn( … )

Das Erstellen einer großen Anzahl verschachtelter Bereiche und Abschlussfunktionen verursacht einen Mehraufwand, sowohl in Bezug auf den Speicher als auch in Bezug auf die Geschwindigkeit Tatsächlich ist der Hauptleistungsengpass in den meisten Anwendungen der Betrieb von DOM-Knoten. Der Leistungsverlust von js ist grundsätzlich vernachlässigbar, sodass Curry direkt und sicher verwendet werden kann.

Curried-Interview-Fragen

// 初步封装
var currying = function(fn) {
    // args 获取第一个方法内的全部参数
    var args = Array.prototype.slice.call(arguments, 1)
    return function() {
        // 将后面方法里的全部参数和args进行合并
        var newArgs = args.concat(Array.prototype.slice.call(arguments))
        // 把合并后的参数通过apply作为fn的参数并执行
        return fn.apply(this, newArgs)
    }
}
    Zusammenfassung
  • Durch die einfache Übergabe einiger Parameter können Sie dynamisch neue Funktionen erstellen. Dies bringt auch einen zusätzlichen Vorteil mit sich, nämlich dass die mathematische Funktionsdefinition erhalten bleibt, obwohl es mehr als einen Parameter gibt .
  • Die Curry-Funktion ist sehr einfach zu bedienen und die tägliche Nutzung macht mir einfach Freude. Es ist ein unverzichtbares Werkzeug, das die funktionale Programmierung weniger umständlich und langweilig macht.

    Weitere Kenntnisse zum Thema Programmierung finden Sie unter: Einführung in die Programmierung! !

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Funktionsrationalisierung in JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen