【ES6 笔记】函数:尾调用优化
2018-10-30 本文已影响0人
___Jing___
尾调用优化是ES6中在系统引擎优化上做的一个改进
概念:尾调用指的是函数作为另一个函数的最后一条语句被调用
function doSomething(){
return doSomethingElse();
};
问题:在ES5中,尾调用的实现与其他函数调用实现类似:创建一个新的栈帧(stack frame),将其推入调用栈来表示函数调用。也就是说,在循环调用中,每一个未用完的栈帧都会被保存在内存中,当调用栈变得过大时会造成程序问题,也就是我们常说的栈溢出(stack overflow)。
ES6中的尾调用优化
如果满足以下条件,尾调用不再创建新的栈帧,而是清除并重用当前栈帧。
- 尾调用不访问当前栈帧的变量(也就是说函数不是一个闭包);
- 在函数内部,尾调用是最后一条语句;
- 尾调用的结果作为函数值返回;
合格示例:
function doSomething(){
return doSomethingElse();
};
以下是反面教材:
function doSomething(){
doSomethingElse(); //没有返回
};
function doSomething(){
return 1+doSomethingElse(); //返回值后还需要做其他操作
};
function doSomething(){
const result = doSomethingElse(); //函数调用不在尾部
return result;
};
function doSomething(){
const num = 1;
const func = () => num //这是一个闭包函数,函数func需要访问局部变量num
return func();
};
如何利用尾调用优化
一般我们在优化函数的时候可能会用到尾调用优化,最常用的场景是在使用递归的时候:
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);
}
}