Ce qui suit provient de l'implémentation de John Hann. Ce code a attiré mon attention. Il utilise une méthode intelligente pour mettre en cache les résultats des appels de méthode.
Analyse du code :
// memoize : Une méthode générale de mise en cache utilisant la mémoisation
// func : méthode à mettre en cache
// contexte : contexte d'exécution de la méthode
// Remarque : La méthode doit être accessible de l'extérieur et les paramètres doivent être sérialisables en caractères
fonction mémoize (func, contexte) {
Function memoizeArg (argPos) { //Le paramètre indique la position du paramètre dans la méthode d'origine
var cache = {}; //La clé de ce cache est le paramètre, et la valeur est le résultat de l'exécution
return function () { //Renvoie une fermeture de fonction
If (argPos == 0) { //Le premier paramètre, si le paramètre n'existe pas dans la clé mise en cache, exécute la fonction d'origine et stocke le résultat de l'exécution
If (!(arguments[argPos] dans le cache)) {
cache[arguments[argPos]] = func.apply(contexte, arguments
);
return cache[arguments[argPos]];
Sinon {// n'est pas le premier paramètre. Si le paramètre n'existe pas dans la clé de cache, il exécute de manière récursive la méthode Memoizearg. La position du paramètre dans la méthode d'origine-1
.
If (!(arguments[argPos] dans le cache)) {
cache[arguments[argPos]] = memoizeArg(argPos - 1
);
return cache[arguments[argPos]].apply(this, arguments);
}
}
var arity = func.arity || func.length; //La longueur du paramètre func, l'attribut length est utilisé en JavaScript et l'attribut arity est utilisé pour les autres
Return memoizeArg(arity - 1); //Recurse du dernier paramètre
>
Utilisation :
Copier le code
alert(mem.call(this,3,1,3));
alert(mem.call(this,2,2,4));
Cela semble simple, mais cela n'est peut-être pas facile à comprendre au premier coup d'œil. Cependant, si vous êtes familier avec l'utilisation des fermetures, ce sera facile à comprendre. Après les plusieurs appels ci-dessus à mem.call, un arbre est formé, chaque nœud est une fermeture, chaque fermeture a un cache et la clé de chaque cache est une branche d'arbre :
(Remarque : le "résultat" dans l'image ci-dessus est également une fermeture, mais argPos est 0)
Mais il existe de nombreuses façons, par exemple, limbboy a dit :
Copier le code
Le code est le suivant :
fonction Mémoize(fn){
var cache = {};
Fonction de retour(){
var clé = [];
for( var i=0, l = arguments.length; i < l; i )
key.push(arguments[i]);
If( !(clé en cache) )
cache[key] = fn.apply(this, arguments);
return cache[clé] ;
};
>
L'implémentation est plus simple, mais placez les paramètres dans un tableau, puis utilisez le tableau comme clé, et la clé ne prend en charge que le type de chaîne, vous devez donc y faire attention lorsque vous l'utilisez (par exemple, un objet ne peut être vu qu'après la chaîne "[object Object]"), sa fonction est plus faible que celle ci-dessus.
Il n'est pas difficile d'améliorer cela. Créez simplement un objet séparé pour le paramètre, et l'objet cache d'origine et cet objet paramètre distinct sont associés à un ID :
fonction Mémoize(fn){
var cache = {}, arguments = {};
Fonction de retour(){
for( var i=0, key = args.length; i < key; i ) {
Si( égal( args[i], arguments ) )
return cache[i]
;
}
args[clé] = arguments
cache[key] = fn.apply(this, arguments);
return cache[clé] ;
};
>
Il existe d'autres méthodes, qui peuvent être écrites sous forme de méthodes fonctionnelles concises.