function* fibs() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
let [first, second, third, fourth, fifth, sixth, seven] = fibs();
sixth // 5
seven // 8
参考
非尾递归的 Fibonacci 数列实现如下:
function fibs(n) {
if(n <= 1) {
return 1;
}
return fibs(n - 1) + fibs(n - 2)
}
尾递归优化过的 Fibonacci 数列实现:
function fibs2(n, ac1 = 1, ac2 = 1) {
if(n <= 1) {
return ac2
}
return fibs2(n - 1, ac2, ac1 + ac2)
}
尾递归的实现,往往需要改写递归函数,确保最后一步只调用自身。做到这一点的方法,就是把所有用到的内部变量改写成函数的参数。比如上面的例子,阶乘函数 factorial 需要用到一个中间变量total,那就把这个中间变量改写成函数的参数。这样做的缺点就是不太直观,第一眼很难看出来,为什么计算5的阶乘,需要传入两个参数5和1?
两个方法可以解决这个问题。方法一是在尾递归函数之外,再提供一个正常形式的函数。
阶乘
function factorial(n) {
if(n === 1) {
return 1
}
return n * factorial(n - 1)
}
尾递归优化之柯里化
function tailFactorial(n, total) {
if(n === 1) {
return total
}
return tailFactorial(n - 1, n * total)
}
function factorial(n) {
return tailFactorial(n, 1)
}
function currying(fn, n) {
return function(m) {
return fn.call(this, m, n)
}
}
function tailFactorial(n, total) {
if(n === 1) return total;
return tailFactorial(n - 1, n * total)
}
function factorial = currying(tailFactorial, 1)
es6 默认值
function factorial(n, total = 1) {
if (n === 1) {
return total;
}
return factorial(n - 1, n * total)
}
网友评论