Javascript 为什么此备忘录实现可以在匿名函数上工作,但不能在声明的函数上工作?
我正在尝试使用memoization来优化Fibonacci函数的显式自递归实现。接下来是相当标准的实现(一个简单且相当幼稚的实现,尽管它关注的是实际问题) 现在,当按如下所示创建和记忆函数时,该函数将起作用1(场景1) 但是,以下情况并非如此。2(场景2) 这也不是。2(场景3) 我的假设是,由于对函数调用Javascript 为什么此备忘录实现可以在匿名函数上工作,但不能在声明的函数上工作?,javascript,recursion,memoization,Javascript,Recursion,Memoization,我正在尝试使用memoization来优化Fibonacci函数的显式自递归实现。接下来是相当标准的实现(一个简单且相当幼稚的实现,尽管它关注的是实际问题) 现在,当按如下所示创建和记忆函数时,该函数将起作用1(场景1) 但是,以下情况并非如此。2(场景2) 这也不是。2(场景3) 我的假设是,由于对函数调用memoize()的方式不同,某些情况正在发生变化。请注意,这些功能在其他方面是相同的。我想这可能是因为除了第一个实例之外,只记录第一个调用,而不是递归调用。 问题 如果我上面的假设确实正确
memoize()
的方式不同,某些情况正在发生变化。请注意,这些功能在其他方面是相同的。我想这可能是因为除了第一个实例之外,只记录第一个调用,而不是递归调用。
问题
如果我上面的假设确实正确,那么为什么会发生这种情况呢?有人能详细解释后两种情况与前两种情况有何不同吗
1在这种情况下工作意味着返回第100个斐波那契数,因为只有在使用记忆的情况下才能递归计算
2不工作会使浏览器崩溃。是的,在第二种和第三种情况下,只有第一个调用会被记忆,这是正确的 在第一种情况下,对原始函数的引用仅作为一个值存在,然后将
memoize
应用于该值,并且fibonacci
变量包含对memoized函数的引用
在第二个和第三个场景中,fibonacci
是对原始函数的引用。表达式fibonaci.memoize()
中包含对memoized函数的引用的值在调用一次之前仅作为值存在
memoize
方法不会更改原始函数,而是返回一个封装原始函数的新函数。原始函数不变,要使用memoization,必须调用memoize
方法返回的函数
在第一个场景中,当函数递归调用
fibonacci
时,使用的是记忆函数。在第二个和第三个场景中,当进行递归调用时,fibonacci
是原始函数。您能再详细说明一下吗?我还是很困惑。@Siddharth:我试过。。。如果这对你没有帮助,你就必须说出你所困惑的是什么。“原始函数是不变的,要使用memonization,你必须调用memonize方法返回的函数。”说到这里,如果我做fibonacci=fibonacci.memonize()代码>在第二个或第三个场景中?更好的问题!
Function.prototype.memoize = function () {
var originalFunction = this,
slice = Array.prototype.slice;
cache = {};
return function () {
var key = slice.call(arguments);
if (key in cache) {
return cache[key];
} else {
return cache[key] = originalFunction.apply(this, key);
}
};
};
var fibonacci = function (n) {
return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}.memoize();
console.log(fibonacci(100));
var fibonacci = function (n) {
return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
};
console.log(fibonacci.memoize()(100));
function fibonacci(n) {
return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}
console.log(fibonacci.memoize()(100));