Javascript 递归-测试最大堆栈大小时调用堆栈无法弹出

Javascript 递归-测试最大堆栈大小时调用堆栈无法弹出,javascript,callstack,event-loop,Javascript,Callstack,Event Loop,基本上,调用堆栈将在最后一次函数调用返回时开始逐个弹出函数调用。但是,每当我试图创建一个接近其最大值的调用堆栈时,就会出现一个未捕获表达式 //Code for testing the stack size var cnt = 0; function test(){ //Max stack size is nearer to ~41800 if(cnt++ == 41763){ console.log('finished'); return true; } return tes

基本上,调用堆栈将在最后一次函数调用返回时开始逐个弹出函数调用。但是,每当我试图创建一个接近其最大值的调用堆栈时,就会出现一个
未捕获表达式

//Code for testing the stack size
var cnt = 0;

function test(){
 //Max stack size is nearer to ~41800
 if(cnt++ == 41763){
  console.log('finished');
  return true;
 }
 return test();
}

test();
因此,上面的代码在chromium 49.0.2623.112 m版中为我抛出了一个异常,如下所示

未捕获异常

请注意,上面的错误中没有消息。我的问题是,

堆栈中的最后一个函数调用返回了
true
,这意味着未超过堆栈大小。为什么堆栈中的其他函数调用没有返回?出现此空白异常消息的原因是什么?

这里的问题是

console.log('finished');
这会在调用堆栈中添加一些额外的函数,这些函数将允许超出限制,但通过异常处理,您的代码仍然会被执行


尝试在不使用console.log的情况下运行它,您会看到达到极限,并看到一个true或一个exception。

console.log不在javascript规范中,因此行为未定义,可以在不同版本之间更改。所以在你的版本中发生的事情在我们的版本中可能不会发生

下面是对发生的情况最可能的解释:可以肯定的是console.log会增加堆栈的大小,并且因为它是您在返回之前调用的最后一条语句,所以它有时会生成一个
最大调用堆栈
,因为您非常接近该限制。最大的调用可能发生在console.log代码(谁调用其他东西)中,这个错误将如何处理,这取决于console.log的代码。当发生错误时,console.log中的代码似乎会抛出一个未捕获的异常。现在,当您用try捕获错误时,代码将继续,这就是为什么会出现true

下面是一个例子,我覆盖了console.log,结果显示在HTML中。您可以通过删除console.log的覆盖代码来查看情况的变化。试试这个,如果结果看起来很奇怪,告诉我们

值得注意的是,当
最大调用堆栈大小超过
错误出现时,它也取决于堆栈帧的大小(局部变量)


注意:在ECMAScript 6中,如果函数调用是函数中的最后一个操作,它将不会进入堆栈,但它将“立即”运行,因此无论您输入的是什么数字,您的代码都将在所有数字上运行而不会出错。

如果我以较少的迭代次数运行此代码(即40763),这很奇怪在刷新页面之前,该错误将消失。在Windows v49.0.2623.87 m上的Chrome中,我收到RangeError:超过最大调用堆栈大小时,超出了它。并返回true-如果不是。可能有帮助吗?1。你为什么需要它?(您可以使用队列来实现它)2。为什么不使用
try…catch
?如果调用堆栈超出了
console.log
的调用范围,那么应该抛出范围错误,为什么它抛出了一个没有消息的异常?console.log是本机代码,javascript中没有函数,所以它没有javascript堆栈跟踪和异常。plus1很好的解释。