Lo siguiente es de la implementación de John Hann, y este código me llamó la atención, que almacenó en caché el resultado de la llamada del método con métodos inteligentes.
Analizador de código:
La copia del código es la siguiente:
// Memoize: un método común para usar la memoización para almacenar en caché
// func: método para almacenar en caché
// contexto: contexto de ejecución de métodos
// NOTA: El método debe ser accesible externamente, y los parámetros están serializados por caracteres
función memoize (func, context) {
función memoizearg (argpos) {// El parámetro indica la posición del parámetro en el método original
var cacheo = {}; // La clave de este caché es el parámetro, y el valor es el resultado de la ejecución
Función de retorno () {// return un cierre de funciones
if (argpos == 0) {// El primer parámetro, si el parámetro no existe en la tecla almacenado en caché, la función original se ejecutará y el resultado de ejecución se almacenará
if (! (argumentos [argpos] en caché)) {
caché [argumentos [argpos]] = func.apply (contexto, argumentos);
}
return cache [argumentos [argpos]];
}
else {// no es el primer parámetro. Si el parámetro no existe en la tecla caché, el método Memoizearg se ejecutará de manera recursiva. La posición del parámetro en el método original -1
if (! (argumentos [argpos] en caché)) {
caché [argumentos [argpos]] = memoizearg (argpos - 1);
}
return cache [argumentos [argpos]]. Aplicar (esto, argumentos);
}
}
}
varity = func.arity || FURC.length; // se usa la longitud del parámetro func, y el atributo arity se usa en JavaScript.
return memoizearg (arity - 1); // La recursión comienza desde el último parámetro
}
usar:
La copia del código es la siguiente:
var mem = memoize (func, this);
alerta (mem.call (this, 1,1,2));
alerta (mem.call (this, 2,1,2));
alerta (mem.call (this, 3,1,3));
alerta (mem.call (this, 2,2,4));
Parece simple, pero no parece fácil de entender cuando lo mira, pero si está familiarizado con el uso de cierres, será fácil de entender. Después de las llamadas anteriores a Mem.call, se forma un árbol. Cada nodo es un cierre, cada cierre tiene un caché y cada llave de caché es una rama de árbol:
(Nota: El "resultado" en la imagen de arriba también es un cierre, pero Argpos es solo 0)
Pero hay muchas maneras, como dijo Limboy:
La copia del código es la siguiente:
función memoize (fn) {
var cacheo = {};
Función de retorno () {
var key = [];
para (var i = 0, l = arguments.length; i <l; i ++)
key.push (argumentos [i]);
if (! (clave en caché))
caché [clave] = fn.apply (this, argumentos);
return cache [clave];
};
}
La implementación es más fácil, pero presione los parámetros en una matriz y luego trate la matriz como una clave, y la clave solo admite el tipo de cadena. Por lo tanto, debe prestar atención a este punto cuando lo usa (por ejemplo, después de una tostración de objeto, solo puede ver "[objeto de objeto]"), y su función es más débil que la anterior.
No es difícil mejorar esto. Simplemente configure otro objeto con el parámetro, y el objeto de caché original y este otro objeto de parámetro están asociados con la ID:
La copia del código es la siguiente:
función memoize (fn) {
var cache = {}, args = {};
Función de retorno () {
para (var i = 0, key = args.length; i <key; i ++) {
if (igual (args [i], argumentos))
return caché [i];
}
args [clave] = argumentos;
caché [clave] = fn.apply (this, argumentos);
return cache [clave];
};
}
Existen otros métodos que se pueden escribir como métodos funcionales concisos.