尾调用优化
概念
某个函数的最后一步是调用另一个函数。
function f(x){
return g(x);
}面代码中,函数f的最后一步是调用函数g,这就叫尾调用。
但是如下代码不是尾调用,尽管语义是一致的。
// 情况一
function f(x){
let y = g(x);
return y;
}
// 情况二
function f(x){
return g(x) + 1;
}尾递归优化
函数调用自身,称为递归。如果尾调用自身,就称为尾递归。
对于尾递归进行优化,能大大减少中间产生的成千上百的调用记录。
例子
上面代码是一个阶乘函数,计算n的阶乘,最多需要保存n个调用记录,复杂度 O(n) 。
如果改写成尾递归,只保留一个调用记录,复杂度 O(1) 。
尾递归的改写
包装改写
上面的例子,阶乘函数 factorial 需要用到一个中间变量 total ,那就把这个中间变量改写成函数的参数。这样做的缺点就是不太直观,第一眼很难看出来,为什么计算5的阶乘,需要传入两个参数5和1?
两个方法可以解决这个问题。方法一是在尾递归函数之外,再提供一个正常形式的函数。
柯里化
ES6 默认参数
最后更新于
这有帮助吗?