我在IE浏览器中特别得到了一些客户端Javascript堆栈溢出问题,这发生在第三方库中,它进行了一些函数调用,并且由于某种原因它们偶尔会因为它的低堆栈限制而在IE中制动.
然后我编写了一个小测试HTML来测试一些浏览器的堆栈大小限制,发现IE8实际上有一个小的堆栈限制,如果与运行在Windows 7操作系统,8Gb RAM的笔记本电脑上的FF 7或Chrome 14相比:
<html>
<body>
<!-- begin Script: -->
<script type="text/javascript">
function doSomething(){
var i = 3200;
doSomethingElse(i);
}
function doSomethingElse(i){
if (i == 0) return -1;
doSomethingElse(i-1);
}
doSomething();
</script>
<!-- END OF PAGE -->
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
当值大约为3200时,IE引发堆栈溢出,如果与IE相比,Firefox和Chrome可以处理非常深的递归.
我想知道是否有办法将堆栈溢出异常与在IE或任何其他浏览器中运行时引发它的Javascript函数联系起来,如果它可以在堆栈中为堆栈跟踪提供堆栈中的函数链提出错误.
我正在尝试使用JavaScript中更实用的样式; 因此,我已经用for实用函数替换了for循环,例如map和reduce.但是,我没有找到while循环的功能替换,因为尾调用优化通常不适用于JavaScript.(根据我的理解,ES6可以防止尾调用溢出堆栈,但不会优化它们的性能.)
我解释了我在下面尝试过的内容,但TLDR是:如果我没有尾调用优化,那么实现while循环的功能方法是什么?
我尝试过的:
创建"while"实用程序功能:
function while(func, test, data) {
const newData = func(data);
if(test(newData)) {
return newData;
} else {
return while(func, test, newData);
}
}
Run Code Online (Sandbox Code Playgroud)
由于尾调用优化不可用,我可以将其重写为:
function while(func, test, data) {
let newData = *copy the data somehow*
while(test(newData)) {
newData = func(newData);
}
return newData;
}
Run Code Online (Sandbox Code Playgroud)
但是在这一点上,感觉就像我让我的代码更复杂/混淆使用它的任何人,因为我必须使用自定义实用程序功能.我看到的唯一实际优势是它迫使我使循环变得纯净; 但似乎只是使用常规while循环并确保我保持一切纯净是更直接的.
我还试图找出一种方法来创建一个模拟递归/循环效果的生成器函数,然后使用像find或reduce这样的实用函数迭代它.但是,我还没有想出一种可读的方法.
最后,用实用函数替换for循环使得我想要完成的更明显(例如,对每个元素做一件事,检查每个元素是否通过了测试等).然而,在我看来,while循环已经表达了我想要完成的事情(例如,迭代直到我们找到素数,迭代直到答案得到充分优化,等等).
所有这一切之后,我的整体问题是:如果我需要一个while循环,我正在以函数式编程,而且我无法访问尾调用优化,那么什么是最佳策略.
javascript recursion functional-programming while-loop tail-call-optimization