我只是想看看我的机器上的最大调用堆栈大小,然后我发现了一些非常奇怪的东西。我有以下两个功能:
function fact(o) {
if (o == 0) return 1;
return o * fact(o - 1)
}
function k(o){
if (o == 0) return;
k(o - 1)
}
调用fact(9644)是我在堆栈溢出之前可以到达的最大数字。例如,fact(9645) 返回错误。
但是,在堆栈溢出之前我最多可以调用 k(10448)。例如,k(10449) 返回错误。
我认为创建函数的方式可能会影响调用堆栈的大小。因此,我尝试将事实设为常量箭头函数,并尝试将其更改为简单的三元评估,例如:
const fact = (o) => o == 0 ? 1 : o * fact(o - 1);
//OR
function fact(o) {
return o == 0 ? 1 : o * fact(o - 1);
}
在分配箭头函数时,我也尝试用let来分配它们,例如:
let fact = (o) => o == 0 ? 1 : o * fact(o - 1);
我用 k 尝试过类似的事情。无论我做什么,结果都保持不变。
(如果重要的话,我在 Chrome Devtools 控制台中运行它。)
此外,经过研究,我得出的结论是,V8 引擎不再进行任何尾递归消除,因此我认为这也不是问题所在。但是,如果我错了,请纠正我。
所以,我的问题是,有人可以告诉我为什么会发生这种情况吗?
为什么堆栈大小因函数而异?
因为不同的函数需要在栈上存储不同的东西。在您的示例中,第一个函数需要在递归调用中保留
o
,第二个函数则不需要。堆栈大小以字节为单位,而不是堆栈帧的数量。