【问题标题】:Why does this memoization implementation work on anonymous functions but not work on declared functions?为什么这个 memoization 实现对匿名函数有效,但对声明函数无效?
【发布时间】:2014-10-13 19:10:39
【问题描述】:

我正在尝试使用记忆来优化斐波那契函数的显式自递归实现。下面是一个相当标准的实现(一个简单且相当幼稚的实现,尽管它专注于实际问题)。

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);
        }
    };
};

现在,当按如下方式创建和记忆函数时,它可以工作1(场景 1)

var fibonacci = function (n) {
    return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}.memoize();

console.log(fibonacci(100));

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

var fibonacci = function (n) {
    return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
};

console.log(fibonacci.memoize()(100));

这也不是。2(场景 3)

function fibonacci(n) {
    return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}

console.log(fibonacci.memoize()(100));

我的假设是,由于在函数上调用 memoize() 的方式不同,某些事情正在发生变化。请注意,这些功能在其他方面是相同的。我想这可能是因为除了第一个实例之外,只有第一个调用被记忆,而不是递归调用。

问题

如果我上面的假设确实是正确的,那么为什么会发生这种情况?谁能详细解释后两种情况与第一种情况有何不同?

1在这种情况下工作意味着返回第 100 个斐波那契数,因为只有使用记忆化才能递归地计算它。

2不工作就是让浏览器崩溃。

【问题讨论】:

  • 更好的问题!

标签: javascript recursion memoization


【解决方案1】:

是的,第二和第三个场景只记忆第一个调用是对的。

在第一种情况下,对原始函数的引用仅作为值存在,然后将 memoize 应用于该值,fibonacci 变量包含对记忆函数的引用。

在第二种和第三种情况下,fibonacci 是对原始函数的引用。包含对记忆化函数的引用的表达式fibonaci.memoize() 的值仅在调用一次之前作为值存在。

memoize 方法不会更改原始函数,而是返回一个包装原始函数的新函数。原函数不变,要使用memoization,必须调用memoize方法返回的函数。

在第一个场景中,当函​​数对fibonacci 进行递归调用时,使用的是记忆化函数。在递归调用的第二种和第三种情况下,fibonacci 是原来的函数。

【讨论】:

  • 您能详细说明一下吗?我还是一头雾水。
  • @Siddharth:我试过了......如果这没有帮助你必须说出你对什么感到困惑。
  • "原函数不变,使用memoization需要调用memoize方法返回的函数。"照这样下去,如果我在第二种或第三种情况下做fibonacci = fibonacci.memoize();怎么样?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-23
  • 1970-01-01
  • 2015-11-26
  • 1970-01-01
相关资源
最近更新 更多