尾调用优化(Tail Call Optimization)

Es6引入的一种内存优化手段,严格模式下会生效
更新于: 2021-12-19 12:57:28

什么是尾调用

  • 尾调用指“函数尾调用”。
  • 尾调用是函数式编程的一个重要概念。
  • 尾调用就是某个函数最后一步是调用另一个函数
  • 这就是一个尾调用
// 函数 f 最后一步调用函数 g,这就是尾调用
function f(x) {
    return g(x);
}

尾调用不一定出现在函数尾部,只要是最后一步操作即可。

// x 等于 5 时,返回 m(x) 的结果,虽然位置不在函数尾部,但是
// 是最后一步操作
function f(x) {
    if (x > 0) {
       return m(x);
    }
    return n(x);
}
f(5) ;

尾调用优化是如何进行的

function f() {
    let m = 1;
    let n = 2;
    return g(m + n);
}
f();

函数 f 最后一步调用函数 g。可以看到,函数 g 被调用时(即 g(3)),已经不依赖父函数 f 中的变量了,那么就可以将函数 f 在内存中占用的空间清除,这就是“尾调用优化”!

你可能想不到,在 ES6 之前,如果子函数运行在内存,那么父函数非得等到子函数运行结束、从内存清除后,才会从内存清除。

尾调用优化需要满足的条件

  • 尾调用函数不需要访问当前栈帧中的变量
  • 函数的最后一步
  • 尾调用返回后,函数没有语句需要继续执行
  • 尾调用的结果就是函数的返回值
  • 严格模式("use strict";)
  • 递归的时候,需要重点考虑这个优化(个人观点)

参考: