Внешняя функция называется _path
. Затем внутри нее строка _path = function _path()
перезаписывает переменную _path
(в настоящее время назначенную функции _path
) другой функцией, называемой _path
.
Таким образом, при выполнении функции перезаписывает самой новой функцией, которая выполняет другую функцию. Вот простая иллюстрация этого принципа:
function f() {
console.log("outer");
f = function f() {
console.log("inner");
}
}
f(); //outer
f(); //inner
f(); //inner
Итак, это , что делает. Что касается , почему это делает это - кэширование. Нужно только посмотреть / вычислить значение один раз, и тогда каждое другое выполнение будет кэшировано. Итак, вот пример, где lookup
- это фиктивный резерв для сетевой операции.
function lookup() {
console.log("making a network call");
return 4;
}
function f() {
var output = lookup();
f = function f() {
return output;
}
return output;
}
console.log(f()); //network call -> 4
console.log(f()); //4
console.log(f()); //4
То же самое можно сделать с тяжелым вычислением, которое не требует сетевого вызова - вместо повторения вычисления и использования циклов ЦП каждый раз, результат может быть вычислен только один раз.
Наконец, почему внутренняя функция называется _path
- нет строгой причины называть это так. Код будет работать так же, даже если у него нет имени. Тем не менее, заменяет внешнюю функцию, поэтому сохранение имени - хорошая идея. Это также может помочь в отладке, когда вы видите трассировку стека.
В общем, эта техника называется памятка . Примечание: это правильное написание, нет r . Хотя я сомневаюсь, что кто-нибудь может запутаться, если вы вставите это.
Во всяком случае, запоминание включает вычисление функции один раз и только возвращение результата через раз. Общий подход состоит в том, чтобы иметь функцию memoize
, с помощью которой можно декорировать другие функции. Вот пример реализации:
function memoize(func) {
//keep a cache for all results
const cache = {};
//make a new function
const memo = function() {
//get the arguments from the input
var key = JSON.stringify(...arguments);
let result;
if (cache.hasOwnProperty(key)) {
//get result from cache
result = cache[key];
} else {
//calculate the result and put it in the cache
result = func(...arguments);
cache[key] = result;
}
return result;
}
return memo;
}
function lookup(data) {
console.log("network call");
return data + 4;
}
function calculate(data) {
console.log("heavy operation");
return data + 2;
}
let memLookup = memoize(lookup);
console.log(memLookup(4)); //network call -> 8
console.log(memLookup(4)); //8
console.log(memLookup(6)); //network call -> 10
console.log(memLookup(6)); //10
let memCalculate = memoize(calculate);
console.log(memCalculate(4)); //heavy operation -> 6
console.log(memCalculate(4)); //6
console.log(memCalculate(6)); //heavy operation -> 8
console.log(memCalculate(6)); //8