Javascript 为什么此备忘录实现可以在匿名函数上工作,但不能在声明的函数上工作?

Javascript 为什么此备忘录实现可以在匿名函数上工作,但不能在声明的函数上工作?,javascript,recursion,memoization,Javascript,Recursion,Memoization,我正在尝试使用memoization来优化Fibonacci函数的显式自递归实现。接下来是相当标准的实现(一个简单且相当幼稚的实现,尽管它关注的是实际问题) 现在,当按如下所示创建和记忆函数时,该函数将起作用1(场景1) 但是,以下情况并非如此。2(场景2) 这也不是。2(场景3) 我的假设是,由于对函数调用memoize()的方式不同,某些情况正在发生变化。请注意,这些功能在其他方面是相同的。我想这可能是因为除了第一个实例之外,只记录第一个调用,而不是递归调用。 问题 如果我上面的假设确实正确

我正在尝试使用memoization来优化Fibonacci函数的显式自递归实现。接下来是相当标准的实现(一个简单且相当幼稚的实现,尽管它关注的是实际问题)

现在,当按如下所示创建和记忆函数时,该函数将起作用1(场景1)

但是,以下情况并非如此。2(场景2)

这也不是。2(场景3)

我的假设是,由于对函数调用
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));