ES6规范新增了一项内存管理机制,让JavaScript能再一定条件下重用栈帧。这项优化非常适合“尾调用”
栈帧使未一个函数单独分配的那部分栈空间
下面我们来看一个栗子
function sonFun() {}
function fatherFun() {
return sonFun()
}
fatherFun()
这段代码是简单的再一个函数中将另一个函数当作返回值返回
这段代码再ES6的内存管理优化机制之前,他是这样运行的
1、首先执行到fatherFun(),然后将这个函数的栈帧推到栈空间
2、然后执行到fatherFun函数体内,到return时,返回sonFun
3、然后执行sonFun,将其的栈帧推到栈上
4、执行sonFun,返回值到fatherFun,然后fatherFun再调用return返回
5、最后将栈帧弹出
ES6对内存优化后的步骤
1、首先执行到fatherFun(),然后将这个函数的栈帧推到栈空间
2、然后执行到fatherFun函数体内,到return时,返回sonFun,然鹅由于fatherFun和sonFun的返回值是一样的。所以
3、引擎将fathenFun弹出栈外,返回sonFun
4、然后执行sonFun的函数体
5、最后将sonFun函数弹出栈外
这样做好处是
无论你要嵌套几个函数,它只有一个栈帧,再抛出下一个运行的函数时,上一个栈帧就已经被销毁。极大的节约栈空间,提高程序运行效率
尾调优化的条件
1、代码运行再严格模式下
2、外部函数的返回值时对尾调函数的调用
3、尾调函数返回不需要执行额外的逻辑
4、尾调函数应用的不是闭包
尾调函数的使用
let oldDate = new Date()
function faFun(x, y, n) {
if (n === 0) {
let date = new Date()
console.log(Number(date))
return date
}
return faFun(y, x + y, n - 1)
}
function son(n) {
return faFun(0, 1, n)
}
let time = son(5000)