O seguinte é da implementação de John Hann, e esse código chamou minha atenção, o que armazenou o resultado da chamada do método com métodos inteligentes.
Código Parsing:
A cópia do código é a seguinte:
// MEMOIZE: Um método comum para usar memórias para cache
// func: método a ser armazenado em cache
// Contexto: contexto de execução do método
// Nota: o método deve ser acessível externamente e os parâmetros são serdidos por caracteres
Função Memoize (func, contexto) {
function memoizearg (argpos) {// o parâmetro indica a posição do parâmetro no método original
var cache = {}; // A chave desse cache é o parâmetro, e o valor é o resultado da execução
Return function () {// retorna uma função Fechamento
se (argpos == 0) {// o primeiro parâmetro, se o parâmetro não existir na chave em cache, a função original será executada e o resultado da execução será armazenado
if (! (Argumentos [argpos] em cache)) {
cache [argumentos [argpos]] = func.apply (contexto, argumentos);
}
Return cache [argumentos [argpos]];
}
else {// não é o primeiro parâmetro. Se o parâmetro não existir na chave em cache, o método Memoizearg será executado recursivamente. A posição do parâmetro no método original -1
if (! (Argumentos [argpos] em cache)) {
cache [argumentos [argpos]] = memorizearg (argpos - 1);
}
Return cache [argumentos [argpos]]. Aplicar (isso, argumentos);
}
}
}
var arity = func.arity || func.length; // O comprimento do parâmetro FUNC é usado e o atributo ARITY é usado no JavaScript.
Retornar Memoizearg (Arity - 1); // A recursão começa no último parâmetro
}
usar:
A cópia do código é a seguinte:
var Mem = Memoize (func, este);
alerta (mem.call (this, 1,1,2));
alerta (mem.call (isto, 2,1,2));
alerta (mem.call (isto, 3,1,3));
alerta (mem.call (isto, 2,2,4));
Parece simples, mas não parece fácil entender quando você olha para ele, mas se você estiver familiarizado com o uso de fechamentos, será fácil entender. Após as chamadas acima para Mem.call, uma árvore é formada. Cada nó é um fechamento, cada fechamento tem um cache e cada chave de cache é um galho de árvore:
(Nota: o "resultado" na figura acima também é um fechamento, mas o argpos é apenas 0)
Mas existem muitas maneiras, como Limboy disse:
A cópia do código é a seguinte:
Função Memoize (FN) {
var cache = {};
Return function () {
var chave = [];
for (var i = 0, l = argumentos.Length; i <l; i ++)
key.push (argumentos [i]);
if (! (chave no cache))
cache [key] = fn.apply (isto, argumentos);
retornar cache [chave];
};
}
A implementação é mais fácil, mas empurre os parâmetros em uma matriz e trate a matriz como uma chave, e a chave suporta apenas o tipo de string. Portanto, você precisa prestar atenção a esse ponto ao usá -lo (por exemplo, após uma tostragem de objeto, você só pode ver "[objeto]") e sua função é mais fraca que a acima.
Não é difícil melhorar isso. Basta configurar outro objeto com o parâmetro, e o objeto de cache original e esse outro objeto de parâmetro estão associados ao ID:
A cópia do código é a seguinte:
Função Memoize (FN) {
var cache = {}, args = {};
Return function () {
for (var i = 0, key = args.length; i <key; i ++) {
if (igual (args [i], argumentos))
retornar cache [i];
}
args [key] = argumentos;
cache [key] = fn.apply (isto, argumentos);
retornar cache [chave];
};
}
Existem alguns outros métodos que podem ser escritos como métodos funcionais concisos.