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实现iframe自动自适应高度的方法
Feb 17 Javascript
在for循环中length值是否需要缓存
Jul 27 Javascript
使用jQuery卸载全部事件的思路详解
Apr 03 jQuery
JS实现图片放大镜插件详解
Nov 06 Javascript
开发Vue树形组件的示例代码
Dec 21 Javascript
红黑树的插入详解及Javascript实现方法示例
Mar 26 Javascript
小程序显示弹窗时禁止下层的内容滚动实现方法
Mar 20 Javascript
mpvue性能优化实战技巧(小结)
Apr 17 Javascript
javascript实现fetch请求返回的统一拦截
Dec 22 Javascript
javascript实现前端分页效果
Jun 24 Javascript
原生js实现表格翻页和跳转
Sep 29 Javascript
node.js通过Sequelize 连接MySQL的方法
Dec 28 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_Flame(Version:Progress)的原代码
2006/10/09 PHP
php你的验证码安全码?
2007/01/02 PHP
PHP中$_SERVER的详细参数与说明介绍
2013/10/26 PHP
PHP判断是否有Get参数的方法
2014/05/05 PHP
destoon实现调用图文新闻的方法
2014/08/21 PHP
CI框架装载器Loader.php源码分析
2014/11/04 PHP
php对接java现实加签验签的实例
2016/11/25 PHP
thinkphp分页集成实例
2017/07/24 PHP
tp5(thinkPHP5)框架连接数据库的方法示例
2018/12/24 PHP
基于javascipt-dom编程 table对象的使用
2013/04/22 Javascript
jQuery中使用Ajax获取JSON格式数据示例代码
2013/11/26 Javascript
浅谈javascript的call()、apply()、bind()的用法
2016/02/21 Javascript
js阻止默认右键的下拉菜单方法
2018/01/02 Javascript
Vue中使用Sortable的示例代码
2018/04/07 Javascript
vue如何通过id从列表页跳转到对应的详情页
2018/05/01 Javascript
小程序实现展开/收起的效果示例
2018/09/22 Javascript
详解在Node.js中发起HTTP请求的5种方法
2019/01/10 Javascript
openlayers4.6.5实现距离量测和面积量测
2020/09/25 Javascript
Vue实现穿梭框效果
2020/09/30 Javascript
[02:53]DOTA2英雄基础教程 山岭巨人小小
2013/12/09 DOTA
[54:45]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 Optic vs OG
2018/04/02 DOTA
pandas中Timestamp类用法详解
2017/12/11 Python
Python3按一定数据位数格式处理bin文件的方法
2019/01/24 Python
python命令行工具Click快速掌握
2019/07/04 Python
Python一键查找iOS项目中未使用的图片、音频、视频资源
2019/08/12 Python
python实现网站微信登录的示例代码
2019/09/18 Python
Python使用psutil获取进程信息的例子
2019/12/17 Python
Python 实现键盘鼠标按键模拟
2020/11/18 Python
美国受欢迎的女性牛仔裤品牌:DL1961
2016/11/12 全球购物
通信生自我鉴定
2014/01/18 职场文书
《匆匆》教学反思
2014/02/22 职场文书
新年联欢会主持词
2014/03/27 职场文书
怎样填写就业意向
2014/04/02 职场文书
合同意向书范本
2014/07/30 职场文书
协议书格式模板
2016/03/24 职场文书
如何撰写创业策划书
2019/06/27 职场文书