一个令人惊讶的简化方法是使用延续传递样式
我们添加一个延续参数k 并为其分配一个默认值console.log。在基本情况下,当 n 小于 2 时,我们用 n 和计数 1 调用延续。在归纳的情况下,n 是 2 或更大,所以我们调用 fib 为 n - 1 和 n - 2,在一个延续中捕获每个的返回值,最后用组合结果调用输入延续,添加一个+ 1 代表当前的n
您还会注意到它不需要全局变量
const fib = (n = 0, k = console.log) =>
n < 2
? k (n, 1)
: fib (n - 1, (a, aCount) =>
fib (n - 2, (b, bCount) =>
k (a + b, aCount + bCount + 1)))
for (let i = 0; i < 10; i = i + 1)
fib (i)
// 0 1
// 1 1
// 1 3
// 2 5
// 3 9
// 5 15 <this is your test case>
// 8 25
// 13 41
// 21 67
// 34 109
默认延续只是记录到控制台,但我们可以提供我们自己的延续来做一些更有趣的结果 - 这也是一种用于模拟返回多个值的技术
for (let n = 0; n < 10; n = n + 1)
fib (n, (res, count) =>
console.log ("after %d computations, fib (%d) returned %d", count, n, res))
// after 1 computations, fib (0) returned 0
// after 1 computations, fib (1) returned 1
// after 3 computations, fib (2) returned 1
// after 5 computations, fib (3) returned 2
// after 9 computations, fib (4) returned 3
// after 15 computations, fib (5) returned 5
// after 25 computations, fib (6) returned 8
// after 41 computations, fib (7) returned 13
// after 67 computations, fib (8) returned 21
这是使用旧 function 语法的相同函数
const fib = function (n = 0, k = console.log) {
if (n < 2)
return k (n, 1)
else
return fib (n - 1, function (a, aCount) {
return fib (n - 2, function (b, bCount) {
return k (a + b, 1 + aCount + bCount)
})
})
}