前言
在ES6的引擎优化中,改变了尾调用系统。
尾调用:
当一个函数的最后一个动作是返回一个函数的调用结果。——维基百科
在ES5中,尾调用就像其他函数调用一样:将调用的函数推送到调用栈。这意味为每个先前的栈帧都保存在内存中,在调用栈太大时会出现问题
在ES6中,只要满足以下条件,就可以清除并重用当前调用帧,而不是创建新的栈帧:
1.尾调用不需要访问当前栈中的变量,即该函数不是闭包
2.在尾调用返回后,进行尾调用的函数没有进一步的工作要做
3.尾调用的结果作为函数值返回
//常见的未优化的递归
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);
}
}
但目前对于浏览器环境而言,尾调递归优化的不具有实际性。
因为各大浏览器厂商并没有部署尾调优化(除Safari)。
v8引擎虽然实现了尾调优化,但考虑到:
尾调用优化依旧有隐式优化和调用栈丢失的问题,
默认是不开启的,开发者也用不了。(详细请见参考的第二篇)
参考文章:
https://github.com/nzakas/understandinges6/blob/master/manuscript/03-Functions.md
https://imweb.io/topic/5a244260a192c3b460fce275
http://kangax.github.io/compat-table/es6/
网友评论