重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。
站在用户的角度思考问题,与客户深入沟通,找到酉阳土家族苗族网站设计与酉阳土家族苗族网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都网站设计、成都网站建设、企业官网、英文网站、手机端网站、网站推广、空间域名、雅安服务器托管、企业邮箱。业务覆盖酉阳土家族苗族地区。
如果你写了一个一直调用自身的死循环,那么恭喜你,很快就可以看到报错:Uncaught RangeError: Maximum call stack size exceeded。那么这个call stack size有多少呢?
1. 计算方法
如下的方法可以为你计算出你使用的JavaScript引擎可以支持多深的调用(由Ben Alman的一段代码获得灵感):
function computeMaxCallStackSize() { try { return 1 + computeMaxCallStackSize(); } catch (e) { // Call stack overflow return 1; } }
运行得到如下三个结果:
这些数字代表了什么呢?Mr.Aleph告诉我在V8,可调用的层数基于两个方面:1. 栈的大小;2. 每一栈帧的大小(用于记录函数参数和局部变量)。你可以在computeMaxCallStackSize声明局部变量来测试,你会发现数字变小。
2. ECMAScript 6中尾递归优化
ECMAScript 6支持尾递归优化:如果一个函数的最后一个操作是函数调用,那么将会用“跳转”而不是“子调用”。也就是说如果你将computeMaxCallStackSize重写成如下形式,在ES6的严格模式下,就会一直运行了。
function computeMaxCallStackSize(size) { size = size || 1; return computeMaxCallStackSize(size + 1); }
3. 亮点评论
var computeMaxCallStackSize = (function() { return function() { var size = 0; function cs() { try { size++; return cs(); } catch(e) { return size + 1; } } return cs(); }; }());