Следующее происходит из реализации Джона Ханна, и этот код привлек мое внимание, которое кэшировало результат вызова метода с помощью умных методов.
Подбор кода:
Кода -копия выглядит следующим образом:
// Memoize: общий метод использования памяти для кэша
// func: метод для кэширования
// контекст: контекст выполнения метода
// Примечание. Метод должен быть извне доступен, а параметры сериализованы символом
Функция запоминает (func, context) {
Функция Memoizearg (argpos) {// Параметр указывает положение параметра в исходном методе
var cache = {}; // Ключ этого кеша является параметром, а значение - результат выполнения
return function () {// возвращать закрытие функции
if (argpos == 0) {// первый параметр, если параметр не существует в клавиш к кэшированию, исходная функция будет выполнена, и результат выполнения будет сохранен
if (! (Arguments [argpos] в кеш)) {
cache [Arguments [argpos]] = func.apply (контекст, аргументы);
}
вернуть кэш [аргументы [argpos]];
}
else {// не первый параметр. Если параметр не существует в кэшированном ключе, метод Memoizearg будет выполнен рекурсивно. Положение параметра в исходном методе -1
if (! (Arguments [argpos] в кеш)) {
кэш [аргументы [argpos]] = memoizearg (argpos - 1);
}
возврат кэша [аргументы [argpos]]. Применить (это, аргументы);
}
}
}
var arity = func.arity || func.length; // используется длина параметра Func, а атрибут ARITY используется в JavaScript.
вернуть Memoizearg (Arity - 1); // рекурсия начинается с последнего параметра
}
использовать:
Кода -копия выглядит следующим образом:
var mem = memoize (func, это);
предупреждение (Mem.Call (это, 1,1,2));
предупреждение (mem.call (это, 2,1,2));
предупреждение (Mem.Call (это, 3,1,3));
предупреждение (mem.call (это, 2,2,4));
Это кажется простым, но, кажется, не просто понять, когда вы смотрите на это, но если вы знакомы с использованием закрытия, это будет легко понять. После приведенных выше вызовов в Mem.Call образуется дерево. Каждый узел является закрытием, каждое закрытие имеет кэш, и каждый ключ кеша - это ветвь дерева:
(Примечание: «результат» на рисунке выше также является закрытием, но Argpos составляет только 0)
Но есть много способов, таких как Лимбой сказал:
Кода -копия выглядит следующим образом:
Функция запоминает (fn) {
var cache = {};
return function () {
var key = [];
для (var i = 0, l = arguments.length; i <l; i ++)
key.push (аргументы [i]);
if (! (ключ в кеше))
cache [key] = fn.apply (это, аргументы);
вернуть кэш [ключ];
};
}
Реализация проще, но подтолкните параметры в массив, а затем рассматривают массив как ключ, а ключ поддерживает только тип строки. Следовательно, вам необходимо обратить внимание на эту точку при использовании его (например, после того, как объект ToString вы можете увидеть только «[объект объекта]»), и его функция слабее, чем вышеуказанный.
Это не сложно улучшить это. Просто настройте другой объект с параметром, а исходный объект кэша и этот другой объект параметра связан с идентификатором:
Кода -копия выглядит следующим образом:
Функция запоминает (fn) {
var cache = {}, args = {};
return function () {
for (var i = 0, key = args.length; i <key; i ++) {
if (равна (args [i], аргументы))
вернуть кэш [i];
}
args [key] = аргументы;
cache [key] = fn.apply (это, аргументы);
вернуть кэш [ключ];
};
}
Есть некоторые другие методы, которые могут быть написаны как краткие функциональные методы.