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 相关文章推荐
javascript编程起步(第六课)
Jan 10 Javascript
jquery 弹出层实现代码
Oct 30 Javascript
js中有关IE版本检测
Jan 04 Javascript
jquery 插件学习(一)
Aug 06 Javascript
在浏览器窗口上添加遮罩层的方法
Nov 12 Javascript
js中split函数的使用方法说明
Dec 26 Javascript
Jquery选择器中使用变量实现动态选择例子
Jul 25 Javascript
js使用Array.prototype.sort()对数组对象排序的方法
Jan 28 Javascript
JavaScript的String字符串对象常用操作总结
May 26 Javascript
用vue封装插件并发布到npm的方法步骤
Oct 18 Javascript
浅谈 Webpack 如何处理图片(开发、打包、优化)
May 15 Javascript
Vue+Element UI+vue-quill-editor富文本编辑器及插入图片自定义
Aug 20 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中const与define的应用区别
2013/06/18 PHP
CI(CodeIgniter)模型用法实例分析
2016/01/20 PHP
Laravel框架实现的批量删除功能示例
2019/01/16 PHP
Discuz! 6.1_jQuery兼容问题
2008/09/23 Javascript
ScrollDown的基本操作示例
2013/06/09 Javascript
纯javascript实现简单下拉刷新功能
2015/03/13 Javascript
jquery读写cookie操作实例分析
2015/12/24 Javascript
javascript自动切换焦点控制效果完整实例
2016/02/02 Javascript
完美的js div拖拽实例代码
2016/09/24 Javascript
Angular 项目实现国际化的方法
2018/01/08 Javascript
微信小程序scroll-view组件实现滚动动画
2018/01/31 Javascript
vue解决使用webpack打包后keep-alive不生效的方法
2018/09/01 Javascript
vue中接口域名配置为全局变量的实现方法
2018/09/20 Javascript
利用Vue-draggable组件实现Vue项目中表格内容的拖拽排序
2019/06/07 Javascript
vue子组件改变父组件传递的prop值通过sync实现数据双向绑定(DEMO)
2020/02/01 Javascript
javascript设计模式 ? 适配器模式原理与应用实例分析
2020/04/13 Javascript
[55:18]Liquid vs Chaos 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
python画柱状图--不同颜色并显示数值的方法
2018/12/13 Python
Python数据可视化之画图
2019/01/15 Python
Python Opencv 通过轨迹(跟踪)栏实现更改整张图像的背景颜色
2020/03/09 Python
如何在keras中添加自己的优化器(如adam等)
2020/06/19 Python
HTML5中原生的右键菜单创建方法
2016/06/28 HTML / CSS
美国宠物美容和宠物用品购物网站:Cherrybrook
2018/12/07 全球购物
婴儿地球:Baby Earth
2018/12/25 全球购物
荷兰时尚精品店:Labels Fashion
2020/03/22 全球购物
.NET程序员的数据库面试题
2012/10/10 面试题
什么是JNDI的上下文?如何初始化JNDI上下文
2012/03/10 面试题
建筑设计所实习生自我鉴定
2013/09/25 职场文书
测绘工程个人的自我评价
2013/11/23 职场文书
员工考核管理制度
2014/02/02 职场文书
捐献物资倡议书范文
2014/05/19 职场文书
2016公务员年度考核评语
2015/12/01 职场文书
辞职信怎么写?你都知道吗?
2019/06/24 职场文书
Go 中的空白标识符下划线
2022/03/25 Golang
Mongodb 迁移数据块的流程介绍分析
2022/04/18 MongoDB
Win11使用CAD卡顿或者致命错误怎么办?Win11无法正常使用CAD的解决方法
2022/07/23 数码科技