函数尾调用优化

尾调用

在编码过程中,经常涉及到函数调用函数,例如:

javascript 复制代码
function a() {
  b();
}

function b() {}

我们每次调用函数,都会在在内存中记录一个"调用帧"又成为"栈帧空间"

在上述例子中,调用a()函数,会在内存中记录一个调用栈,然后继续调用b()函数,此时在内存中又会记录一个调用帧,等到b()函数运行结束,调用帧a、b的内存才会释放。

我们可以利用"尾调用"来释放调用帧内存

javascript 复制代码
function a() {
  return b();
}

function b() {}

上述代码中,在函数的最后一步调用了b()函数,外层函数内存直接被释放,确认代之的是b()函数内存被创建,从复杂度来看,普通调用复杂度O(n),尾调用复杂度O(1)

尾调用并不是函数中的最后一行,而是最后一步,在下面的例子中,也可以实现尾调用

javascript 复制代码
function a(n) {
  if(n === 5){
    return b();  // 尾调用
  }
  return c(); // 尾调用
}

尾递归

递归函数就是函数调用自身,正常的递归函数会进行深层调用,每次调用函数都会创建内存,也就是上面所说的调用帧,直到递归函数执行完毕,内存才会被释放,如果递归函数层级过深,记录栈帧过多,会导致栈溢出错误。

我们可以利用尾调用来优化并释放内存,下面是一个尾递归函数

javascript 复制代码
/* 尾递归 */
function tailRecur(n, res) {
    // 终止条件
    if (n === 0) return res;
    // 尾递归调用
    return tailRecur(n - 1, res + n);
}
相关推荐
search71 小时前
前端设计:CRG 3--CDC error
前端
治金的blog1 小时前
vben-admin和vite,ant-design-vue的结合的联系
前端·vscode
利刃大大2 小时前
【Vue】Vue2 和 Vue3 的区别
前端·javascript·vue.js
Lhuu(重开版2 小时前
JS:正则表达式和作用域
开发语言·javascript·正则表达式
荔枝一杯酸牛奶3 小时前
HTML 表单与表格布局实战:两个经典作业案例详解
前端·html
Charlie_lll4 小时前
学习Three.js–纹理贴图(Texture)
前端·three.js
yuguo.im4 小时前
我开源了一个 GrapesJS 插件
前端·javascript·开源·grapesjs
安且惜4 小时前
带弹窗的页面--以表格形式展示
前端·javascript·vue.js
米奇妙妙wuu4 小时前
css实现文字和边框同样的渐变色效果
css·html·css3
摘星编程5 小时前
React Native鸿蒙:BiometricAuth指纹解锁实现
react native·react.js·harmonyos