图解尾调用优化

栏目: JavaScript · 发布时间: 7年前

内容简介:啥是尾调用?尾调用就是函数的最后一个步骤调用另一个函数比方说:

图解尾调用优化

尾调用

啥是尾调用?

尾调用就是函数的最后一个步骤调用另一个函数

比方说:

图解尾调用优化

函数在调用的时候会在调用栈中 push 一个调用帧,每次执行完函数都会逐一弹出调用帧知道所有函数执行完毕,调用栈被清空:

调用栈中的同步代码

function f1() { console.log(':apple:') }
function f2() { f1() }
function f3() { f2() }

f3()

调用栈如下图:

图解尾调用优化

  • 首先执行 script ,将 main 主程序推入调用栈中并执行,发现需要调用 f3
  • 将 f3 函数推入调用栈中,执行 f3,发现需要调用 f2
  • 将 f2 函数推入调用栈中,执行 f2, 发现需要调用 f1
  • 将 f1 推入调用栈中,执行 f1,发现需要调用 console.log 方法
  • 推入 console.log 并打印结果执行完毕
  • 弹出 consoole.log
  • 弹出 f1
  • 弹出 f2
  • 弹出 f3
  • 弹出 main,代码执行完毕

调用栈中的异步代码

以 setTimeout 为例:

console.log('1')
setTimeout(function() {
    console.log('3)
}, 5000)
console.log('2')

调用栈见下图:

图解尾调用优化

  • 执行代码推入 script 代码 main 并执行,发现需要执行 console.log
  • 将 console.log 推入调用栈
  • 执行 console.log 打印 1 弹出调用栈
  • 发现 setTimeout 将等待执行的回调函数推入宏任务列表,将 setTimeout 弹出调用栈
  • 继续执行代码发现需要执行 console.log 将任务推入调用栈
  • 执行 console.log 打印 2 并弹出调用栈
  • script 代码 main 执行完毕,弹出调用栈
  • 同步代码执行完毕,查看宏任务列表发现需要执行 console.log
  • 延迟 5s 将 console.log 推入调用栈
  • 执行 console.log 并打印 2
  • 最后将 console.log 弹出调用栈,代码执行完毕

尾调用优化

每次在函数被调用的时候,内存都会保存调用帧。尾调用因为是函数的最后一步,因此并不需要外层函数的调用帧。我们只需要将最后需要执行另外一个函数之前用 return 操作符显式表明"不再需要此函数"即可

图解尾调用优化

before

图解尾调用优化

after

注意必须使用严格模式

在执行过程中,调用栈的调用帧永远只有一条,这样就可以节省很大一部分内存

参考:

图解尾调用优化


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

Beautiful Code

Beautiful Code

Greg Wilson、Andy Oram / O'Reilly Media / 2007-7-6 / GBP 35.99

In this unique work, leading computer scientists discuss how they found unusual, carefully designed solutions to difficult problems. This book lets the reader look over the shoulder of major coding an......一起来看看 《Beautiful Code》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具