2010-04-18 86 views
4

当我正在阅读书籍Javascript:The Good Parts。我不明白这块代码波纹管:Javascript关闭问题

我们可以通过进行 功能可以让我们memoized 功能概括这一点。 memoizer功能将 采取初始备忘录阵列和 基本功能。它返回一个 shell函数,该函数管理备忘录 存储,并根据需要调用基本函数 函数。我们通过壳 函数和函数的参数 的基本功能:

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

现在,我们可以用 memoizer定义斐波那契数,提供初始备忘录 阵列和基本功能:

var fibonacci = memoizer([0, 1], function (test, n) { 
    return test(n - 1) + test(n - 2); 
}); 

我的问题是什么是测试功能?它什么时候被定义和调用?这对我来说似乎很困惑。另外我认为这种说法:memo[n] = result;是无用的。如果我错了,请纠正。

+0

哇。作为一个功能很少的编程知识的人,这段代码让我大开眼界。这太聪明了! – dmb 2010-04-18 03:00:19

+0

相关:[关于“JavaScript - 良好部件”示例(第4.15节)的说明?](https://stackoverflow.com/questions/3798858/explanation-on-javascript-the-good-parts-example-section-4 -15) – Bergi 2014-05-30 13:57:08

回答

1

语句memo[n] = result;将新计算的数字存储在记忆数组或缓存中。 test函数是要被记忆的函数的参数,并且由memoizer定义和传递。调用时,它会检查要计算的值是否已被缓存。如果是这样,它从缓存中返回它。否则,它会再次重新计算。

执行上述所有代码之后,我们得到的记忆是这样的(但与memo阵列和orig_fibonacci封装):

var memo = [0, 1]; 

function fibonacci(n) { 
    var result = memo[n]; 
    if (typeof result != 'number') { 
    result = orig_fibonacci(n); 
    memo[n] = result; 
    } 
    return result; 
} 

function orig_fibonacci(n) { 
    return fibonacci(n - 1) + fibonacci(n - 2); 
} 
4

这是一个有趣的代码片段阅读:)

您可能知道memoization正在存储函数的结果,所以下次调用该函数时,它不必计算答案,只需查看它即可。

所以我们需要存储fibonacci函数的答案,它接受一个int并返回一个int。

var fibonacci = memoizer([0, 1], function (test, n) { 
    return test(n - 1) + test(n - 2); 
}); 

使用初始备忘录数组调用memoizer,映射fib(0) - > 0和fib(1) - > 1。

其余的定义了一个未命名的函数,它带有一个函数和一个数字。 '测试'是一个坏名字,它应该是“recursive_fibonacci_helper”:)

这个未命名的函数成为“基本”参数。 memoizer函数返回一个函数(shell),它接受一个int参数。这最终成为斐波纳契函数。

所以当有人说“斐波那契(5)”。他们真的叫“壳(5)”。关于关闭的重要部分是“基本”和“备忘录”已经绑定。

那么'shell'是做什么的?

它在备忘录表中查找它是否已经为该输入计算出答案。如果它看到一个答案(=='数字'),那么它会返回它。否则,它会计算它并将其存储在备忘录表中。 memo[n] = result实际上是将计算结果存储在记忆表中。