什么是尾调用,使用尾调用有什么好处?

一、什么是尾调用

尾调用就是在函数执行的最后一步调用另一个函数。

如下所示为尾调用:

function f(x) {
	return g(x)
}

function b(num) {
  return c(num + 2)
}

下面的两种情况都不属于尾调用:

function f(x){
	let y = g(x)
	return y
}
function f(x){
	return g(x) + 1
}

二、为什么说尾调用的性能要比没有使用尾调用的性能好呢?

代码执行是基于执行栈的,所以当在一个函数里调用另一个函数时,会保留当前的执行上
下文,然后再新建另外一个执行上下文加入栈中,这样比较占用内存;

而使用尾调用的话,因为已经是函数的最后一步,执行尾调用函数时,就可以不必再保留当前执行的上下文,从而节省了内存,这就是尾调用优化。

但是 ES6 的尾调用优化只在严格模式下开启,正常模式是无效的。

三、尾递归

函数调用自身,叫做递归。如果尾调用自身,则就称为尾递归。

递归非常消耗内存,因为需要同时保存成千上万个调用记录,很容易发生栈溢出的错误。

但是对于尾递归来说,由于只存在一个调用记录,所以永远不会发生栈溢出。

  • 求阶乘的递归 ---- 容易造成内存的泄露
function factorial(n) {
  if (n === 1) return 1
  return n * factorial(n - 1)
}

console.log(factorial(5)) //120
  • 求阶乘的递归,优化成尾递归,
function factorial(n, total) {
  if (n === 1) return total
  return factorial(n - 1, total * n)
}

console.log(factorial(5, 1))

如上述代码所示,我们使用尾递归,fatorial(5, 1)的值也就是factorial(4, 5)的值,同时也是factorial(3, 20)…这样调用栈中,每一次都只有一个函数,不会导致内存泄露。

四、严格模式

ES6中的尾调用优化只在严格模式下开启,正常模式下无效。

这是因为在正常模式下,函数内部有两个变量,可以跟踪函数的调用栈。严格模式下禁用这两个变量,所以尾调用模式仅在严格模式下生效。

参考地址:https://blog.csdn.net/weixin_47450807/article/details/123396329

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值