企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] >[success] # 尾调用优化 ~~~ '尾调用优化'使用场景,一般在'递归'时使用会有显著效果,在'ES6'中对函数最有趣的改动或许就是一项 '引擎优化',它改变了'尾部调用'的系统。'尾调用'指的是调用函数的语句是'另一个函数的最后语句',有3点, 符合这'3'点就是达成了'尾调用优化' 1. 尾调用不能引用当前栈帧中的变量(意味着'该函数不能是闭包') 2. 进行尾调用的函数在'尾调用返回结果后不能做额外操作' 3. 尾调用的结果作为当前函数的返回值 ~~~ ~~~ function doSomething() { return doSomethingElse() // 尾调用 } ~~~ <br/> >[danger] ## 错误尾调用优化案例 1. 没有return ~~~ "use strict" function doSomething() { doSomethingElse() // 未被优化:缺少 return } ~~~ 2. 在return时候还进行加法操作 ~~~ "use strict" function doSomething() { return 1 + doSomethingElse() // 未被优化:在返回之后还要执行加法 } ~~~ 3. 将函数调用的结果储存在一个变量上,之后才返回了 结果 ~~~ "use strict" function doSomething() { let result = doSomethingElse() // 未被优化:调用并不在尾部 return result } ~~~ 4. 闭包能够访问上层作用域的变量,会导致尾 调用优化被关闭 ~~~ "use strict"; function doSomething() { let num = 1, func = () => num return func() // 未被优化:此函数是闭包 } ~~~ <br/> >[success] ## 如何控制尾调用优化 ~~~ 在实践中,'尾调用优化在后台进行',所以不必对此考虑太多,除非要尽力去优化一个函数。尾调用优化的主要用 例是在'递归函数'中,而且在其中的优化具有最大效果。考虑以下计算阶乘的函数: ~~~ 优化前: ~~~ // 阶乘递归 function factorial(n) { if (n <= 1) { return 1 } else { // 未被优化:在返回之后还要执行乘法 return n * factorial(n - 1) } } ~~~ 优化后: ~~~ function factorial(n, p = 1) { if (n <= 1) { return 1 * p } else { let result = n * p // 被优化 return factorial(n - 1, result) } } ~~~