JS的函数调用栈stack size的计算方法


Posted in Javascript onJune 24, 2018

如果你写了一个一直调用自身的死循环,那么恭喜你,很快就可以看到报错: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;
    }
  }

运行得到如下三个结果:

  • Node.js: 11034
  • Firefox: 50994
  • Chrome: 10402

这些数字代表了什么呢?Mr.Aleph告诉我在V8,可调用的层数基于两个方面:1. 栈的大小;2. 每一栈帧的大小(用于记录函数参数和局部变量)。你可以在computeMaxCallStackSize声明局部变量来测试,你会发现数字变小。

2. ECMAScript 6中尾递归优化

ECMAScript 6支持尾递归优化:如果一个函数的最后一个操作是函数调用,那么将会用“跳转”而不是“子调用”。也就是说如果你将computeMaxCallStackSize重写成如下形式,在ES6的严格模式下,就会一直运行了。

function computeMaxCallStackSize(size) {
    size = size || 1;
    return computeMaxCallStackSize(size + 1);
  }

3. 亮点评论

Andrei: “ECMAScript 6”版本的代码根本跑不通。虽然size会被更改,但是最终并没有值返回。

回复Andrei: 有趣!你不能用这段代码去计算stack size。在ES6下,这段代码会一直运行,因此不会返回数据。在其它情况下,会返回RangeError。为了使其工作,我把代码重写了一下:

var computeMaxCallStackSize = (function() {
 return function() {
  var size = 0;
  function cs() {
   try {
    size++;
    return cs();
   } catch(e) {
    return size + 1;
   }
  }
  return cs();
 };
}());
Javascript 相关文章推荐
js表格分页实现代码
Sep 18 Javascript
jQuery EasyUI API 中文文档 - Calendar日历使用
Oct 19 Javascript
解决extjs grid 不随窗口大小自适应的改变问题
Jan 26 Javascript
详解基于Bootstrap扁平化的后台框架Ace
Nov 27 Javascript
js实现延迟加载的几种方法
Apr 24 Javascript
jQuery Validate表单验证插件实现代码
Jun 08 jQuery
微信小程序实现收藏与取消收藏切换图片功能
Aug 03 Javascript
django使用channels2.x实现实时通讯
Nov 28 Javascript
详解Vue源码之数据的代理访问
Dec 11 Javascript
vue使用prop可以渲染但是打印台报错的解决方式
Nov 13 Javascript
JavaScript JSON使用原理及注意事项
Jul 30 Javascript
如何在JavaScript中等分数组的实现
Dec 13 Javascript
JavaScript中var、let、const区别浅析
Jun 24 #Javascript
使用JavaScript中的lodash编写双色球效果
Jun 24 #Javascript
Vue中$refs的用法详解
Jun 24 #Javascript
JS实现获取word文档内容并输出显示到html页面示例
Jun 23 #Javascript
纯JS实现的读取excel文件内容功能示例【支持所有浏览器】
Jun 23 #Javascript
Vue子组件向父组件通信与父组件调用子组件中的方法
Jun 22 #Javascript
Vue验证码60秒倒计时功能简单实例代码
Jun 22 #Javascript
You might like
PHP脚本的10个技巧(7)
2006/10/09 PHP
如何使用PHP往windows中添加用户
2006/12/06 PHP
php中批量修改文件后缀名的函数代码
2011/10/23 PHP
php微信公众平台开发(三)订阅事件处理
2016/12/06 PHP
php PDO判断连接是否可用的实现方法
2017/04/03 PHP
解决form中action属性后面?传递参数 获取不到的问题
2017/07/21 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
ext 同步和异步示例代码
2009/09/18 Javascript
为JavaScript提供睡眠功能(sleep) 自编译JS引擎
2010/08/16 Javascript
jquery处理json数据实例分析
2014/06/03 Javascript
javascript中attribute和property的区别详解
2014/06/05 Javascript
从JQuery源码分析JavaScript函数的apply方法与call方法
2014/09/25 Javascript
浅谈jQuery双事件多重加载的问题
2016/10/05 Javascript
select自定义小三角样式代码(实用总结)
2017/08/18 Javascript
利用nginx + node在阿里云部署https的步骤详解
2017/12/19 Javascript
jquery radio 动态控制选中失效问题的解决方法
2018/02/28 jQuery
VUE2.0+ElementUI2.0表格el-table循环动态列渲染的写法详解
2018/11/30 Javascript
vue 实现单选框设置默认选中值
2019/11/07 Javascript
vue项目打包之开发环境和部署环境的实现
2020/04/23 Javascript
python中使用pyhook实现键盘监控的例子
2014/07/18 Python
详解使用Python处理文件目录的相关方法
2015/10/16 Python
基于python的Tkinter实现一个简易计算器
2015/12/31 Python
Python基本数据结构之字典类型dict用法分析
2019/06/08 Python
Python Handler处理器和自定义Opener原理详解
2020/03/05 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
2020/06/18 Python
为什么相对PHP黑python的更少
2020/06/21 Python
REN Clean Skincare官网:英国本土有机护肤品牌
2019/02/23 全球购物
PHP解析URL是哪个函数?怎么用?
2013/05/09 面试题
一套带答案的C++笔试题
2014/01/10 面试题
掌上明珠Java程序员面试总结
2016/02/23 面试题
电子专业推荐信范文
2013/11/18 职场文书
中学教师教育感言
2014/02/21 职场文书
2014婚礼司仪主持词
2014/03/14 职场文书
2014年少先队工作总结
2014/12/03 职场文书
大队委员竞选演讲稿
2015/11/20 职场文书
小程序实现筛子抽奖
2021/05/26 Javascript