Javascript之尾调优化
优化的前提
ES6的尾调用优化只在严格模式下开启,正常模式是无效的。
这是因为在正常模式下,函数内部有两个变量,可以跟踪函数的调用栈。
arguments:返回调用时函数的参数。
func.caller:返回调用当前函数的那个函数。
尾调用优化发生时,函数的调用栈会改写,因此上面两个变量就会失真。严格模式禁用这两个变量,所以尾调用模式仅在严格模式下生效。
没有使用尾调优化
先看一个阶乘代码示例:
function foo(x) {
if (x <= 1) {
return 1;
}
return x * foo(x - 1);
}
foo函数在调用自身时,会占用额外的栈空间,因为每次调用都需要保存当前的上下文。
尾调优化的好处
可以在函数运行结束时,直接跳转到新的函数调用处,而不是创建一个新的栈帧。这样可以减少内存的占用,特别是在递归深度较大的时候非常有用。
"use strict";
function foo(x) {
return bar(x); // 直接调用bar,而不是返回一个值后再调用。
}
function bar(x, acc = 1) {
if (x <= 1) {
return acc; // 直接返回累积的结果,而不是再次调用foo。
}
return bar(x - 1, x * acc);
}
foo(5); // 120