关于"JavaScript - 好零件"示例的说明(第4.15节)?

Max*_*Max 7 javascript memoization

JS中的初学者需要解释Crockford的书中的代码片段4.15节:

var memoizer = function (memo, fundamental) {
    var shell = function (n) {
        var result = memo[n];
        if (typeof result !== 'number') {
            result = fundamental(shell, n);
            memo[n] = result;
        }
        return result;
    };
    return shell;
};

var fibonacci = memoizer([0, 1], function (shell, n) {
    return shell(n - 1) + shell(n - 2);
});
Run Code Online (Sandbox Code Playgroud)

问题:我们如何计算斐波那契(15),如果它是简单的斐波纳契(15)调用,那它的工作原理如何?

感谢帮助.

Fin*_*nNk 1

正如对您的问题的评论所建议的那样,如果您无法遵循书中的解释,您应该在调试器中浏览代码,以便更好地理解正在发生的情况。但我将向您简要概述正在发生的事情:

所演示的是“记忆化”,这是函数式编程中常用的优化技术。如果结果仅取决于传递给函数的参数,则称函数是纯函数。因此,如果一个函数是纯函数,您可以根据参数缓存结果 - 这种技术称为记忆化。如果一个函数的计算成本很高并且被多次调用,您就可以这样做。

用于演示这一点的经典示例(如此处)是生成斐波那契数。我不会详细介绍这些是如何计算出来的,但基本上,当你得到越来越大的数字时,你会越来越多地重复自己,因为每个数字都是根据前面的两个数字计算出来的。通过记住每个中间结果,您只需计算一次,从而使算法更快(当您在序列中走得更高时,速度会快得多)。

就这段代码而言,memoizer 采用两个参数 - “memo”,即缓存。在本例中,它将使用已填充“[0,1]”的前两个值 - 这些是前两个斐波那契数。

第二个参数是将应用记忆的函数。在这种情况下,递归斐波那契函数:

函数 (shell, n) { 返回 shell(n - 1) + shell(n - 2); }

即结果是序列中前两个数字的总和。

存储器首先检查它是否已经有缓存的结果。如果确实如此,它会立即返回。如果不是,则计算结果并将其存储在缓存中。如果不这样做,它就会一次又一次地重复,并且一旦达到序列中更高的数字,速度就会变得非常慢。