Das Folgende stammt aus der Implementierung von John Hann, und dieser Code erregte meine Aufmerksamkeit, wodurch das Ergebnis der Methodenaufruf mit cleveren Methoden zwischengespeichert wurde.
Code Parsen:
Die Codekopie lautet wie folgt:
// Memoize: Eine gemeinsame Methode zur Verwendung von Memoisierung zum Cache
// func: Methode, die zwischengespeichert werden soll
// Kontext: Methodenausführung Kontext
// Hinweis: Die Methode muss extern zugänglich sein, und die Parameter sind charakterisiert
Funktion memoize (func, context) {
Funktionsmemoizearg (argpos) {// Der Parameter zeigt die Position des Parameters im ursprünglichen Verfahren an
var cache = {}; // Der Schlüssel dieses Cache ist der Parameter, und der Wert ist das Ausführungsergebnis
return function () {// Rückschließung zurück
if (argpos == 0) {// Der erste Parameter, wenn der Parameter in der zwischengespeicherten Taste nicht vorhanden ist, wird die ursprüngliche Funktion ausgeführt und das Ausführungsergebnis wird gespeichert
if (! (Argumente [argpos] im Cache)) {
Cache [Argumente [argpos]] = func.apply (Kontext, Argumente);
}
Cache zurückgeben [Argumente [argpos]];
}
sonst {// nicht der erste Parameter. Wenn der Parameter in der zwischengespeicherten Taste nicht vorhanden ist, wird die Memoizearg -Methode rekursiv ausgeführt. Die Position des Parameters in der ursprünglichen Methode -1
if (! (Argumente [argpos] im Cache)) {
Cache [Argumente [argpos]] = memoizearg (argpos - 1);
}
Cache zurückgeben [Argumente [argpos]]. Bewerben Sie (dies, Argumente);
}
}
}
var arity = func.arity || func.length; // Die Länge des Func -Parameters wird verwendet und das Arity -Attribut wird in JavaScript verwendet.
Return Memoizearg (Arity - 1); // Recursion startet vom letzten Parameter
}
verwenden:
Die Codekopie lautet wie folgt:
var mem = memoize (func, this);
Alert (Mem.Call (this, 1,1,2));
Alert (mem.call (this, 2,1,2));
Alert (mem.call (this, 3,1,3));
Alert (Mem.call (this, 2,2,4));
Es scheint einfach zu sein, aber es scheint nicht leicht zu verstehen, wenn Sie es betrachten, aber wenn Sie mit der Verwendung von Schließungen vertraut sind, wird es leicht zu verstehen sein. Nachdem die oben genannten Aufrufe zu Mem.call, wird ein Baum gebildet. Jeder Knoten ist ein Verschluss, jeder Verschluss hat einen Cache und jede Cache -Taste ist ein Baumzweig:
(Hinweis: Das "Ergebnis" im obigen Bild ist ebenfalls ein Verschluss, aber Argpos ist nur 0)
Aber es gibt viele Möglichkeiten, wie Limboy sagte:
Die Codekopie lautet wie folgt:
Funktion Memoize (fn) {
var cache = {};
return function () {
var key = [];
für (var i = 0, l = argumente.length; i <l; i ++)
Key.push (Argumente [i]);
if (! (Schlüssel im Cache)))
cache [key] = fn.apply (this, Argumente);
Cache zurückgeben [Schlüssel];
};
}
Die Implementierung ist einfacher, aber die Parameter in ein Array drücken und dann das Array als Schlüssel behandeln, und der Schlüssel unterstützt nur den String -Typ. Daher müssen Sie auf diesen Punkt achten, wenn Sie ihn verwenden (z. B. nach einem Objekt -Tostring können Sie nur "[Objektobjekt]" sehen) und seine Funktion ist schwächer als die obige.
Es ist nicht schwierig, dies zu verbessern. Richten Sie einfach ein anderes Objekt mit dem Parameter ein, und das ursprüngliche Cache -Objekt und dieses andere Parameterobjekt sind der ID zugeordnet:
Die Codekopie lautet wie folgt:
Funktion Memoize (fn) {
var cache = {}, args = {};
return function () {
für (var i = 0, key = args.length; i <key; i ++) {
if (gleich (args [i], Argumente))
Cache zurückgeben [i];
}
args [Schlüssel] = Argumente;
cache [key] = fn.apply (this, Argumente);
Cache zurückgeben [Schlüssel];
};
}
Es gibt einige andere Methoden, die als präzise Funktionsmethoden geschrieben werden können.