详解JS函数stack size计算方法


Posted in Javascript onJune 18, 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 相关文章推荐
DOM 脚本编程中的兄弟节点
Oct 31 Javascript
JavaScript 类似flash效果的立体图片浏览器
Feb 08 Javascript
能说明你的Javascript技术很烂的五个原因分析
Oct 28 Javascript
javascript上下方向键控制表格行选中并高亮显示的方法
Feb 13 Javascript
javaScript中Math()函数注意事项
Jun 18 Javascript
jquery 动态增加删除行的简单实例(推荐)
Oct 12 Javascript
JavaScript中${pageContext.request.contextPath}取值问题及解决方案
Dec 08 Javascript
VUE axios上传图片到七牛的实例代码
Jul 28 Javascript
ES6模块化的import和export用法方法总结
Aug 08 Javascript
jQuery 1.9版本以上的浏览器判断方法代码分享
Aug 28 jQuery
JS中async/await实现异步调用的方法
Aug 28 Javascript
微信小程序制作扭蛋机代码实例
Sep 24 Javascript
jQuery使用动画队列自定义动画操作示例
Jun 16 #jQuery
node.js自动上传ftp的脚本分享
Jun 16 #Javascript
Vue中props的使用详解
Jun 15 #Javascript
基于jQuery实现的设置文本区域的光标位置
Jun 15 #jQuery
深入浅析Vue全局组件与局部组件的区别
Jun 15 #Javascript
react-native android状态栏的实现
Jun 15 #Javascript
JS实现监控微信小程序的原理
Jun 15 #Javascript
You might like
杏林同学录(五)
2006/10/09 PHP
用PHP查询域名状态whois的类
2006/11/25 PHP
php正则表达式使用的详细介绍
2013/04/27 PHP
基于JQuery的密码强度验证代码
2010/03/01 Javascript
ajax提交表单实现网页无刷新注册示例
2014/05/08 Javascript
JS实现带有抽屉效果的产品类网站多级导航菜单代码
2015/09/15 Javascript
JavaScript jQuery 中定义数组与操作及jquery数组操作
2015/12/18 Javascript
浅析Bootstrap组件之面板组件
2016/05/04 Javascript
基于JavaScript实现轮播图代码
2016/07/14 Javascript
jquery popupDialog 使用 加载jsp页面的方法
2016/10/25 Javascript
Bootstrap基本插件学习笔记之标签切换(17)
2016/12/08 Javascript
jQuery实现简易的输入框字数计数功能示例
2017/01/16 Javascript
详解vue-router 命名路由和命名视图
2018/06/01 Javascript
JS面向对象之单选框实现
2020/01/17 Javascript
Vuejs通过拖动改变元素宽度实现自适应
2020/09/02 Javascript
[02:49]DOTA2完美大师赛首日观众采访
2017/11/23 DOTA
基于python中staticmethod和classmethod的区别(详解)
2017/10/24 Python
python shell根据ip获取主机名代码示例
2017/11/25 Python
Python使用add_subplot与subplot画子图操作示例
2018/06/01 Python
python numpy 一维数组转变为多维数组的实例
2018/07/02 Python
pyinstaller打包单个exe后无法执行错误的解决方法
2019/06/21 Python
python中wx模块的具体使用方法
2020/05/15 Python
python 模块导入问题汇总
2021/02/01 Python
css3 media 响应式布局的简单实例
2016/08/03 HTML / CSS
HTML5中div、article、section的区别及使用介绍
2013/08/14 HTML / CSS
HTML5语音识别标签写法附图
2013/11/18 HTML / CSS
HTML5实现签到 功能
2018/10/09 HTML / CSS
C#如何调用Word并打开一个Word文档
2013/05/08 面试题
软件工程师岗位职责
2013/11/16 职场文书
办护照工作证明范本
2014/01/14 职场文书
商务邀请函范文
2014/01/14 职场文书
人力资源管理专业求职信
2014/07/23 职场文书
春季运动会开幕词
2015/01/28 职场文书
清明祭英烈活动总结
2015/05/11 职场文书
2016三八妇女节慰问信
2015/11/30 职场文书
通知怎么写?
2019/04/17 职场文书