详解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 相关文章推荐
javascript格式化日期时间方法汇总
Jun 19 Javascript
AngularJS中的过滤器filter用法完全解析
Apr 22 Javascript
老生常谈js动态添加事件--- 事件委托
Jul 19 Javascript
Bootstrap和Angularjs配合自制弹框的实例代码
Aug 24 Javascript
JavaScript标准对象_动力节点Java学院整理
Jun 27 Javascript
JavaScript实现的原生态Tab标签页功能【兼容IE6】
Sep 18 Javascript
Node.Js生成比特币地址代码解析
Apr 21 Javascript
webpack打包非模块化js的方法
Oct 24 Javascript
如何用RxJS实现Redux Form
Dec 29 Javascript
layui字体图标 loading图标静止不旋转的解决方法
Sep 23 Javascript
vue 使用 canvas 实现手写电子签名
Mar 06 Javascript
vue实现登陆页面开发实践
May 30 Vue.js
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
PHP音乐采集(部分代码)
2007/02/14 PHP
php入门学习知识点六 PHP文件的读写操作代码
2011/07/14 PHP
php学习笔记之面向对象编程
2012/12/29 PHP
PHP 正则判断中文UTF-8或GBK的思路及具体实现
2013/11/26 PHP
php微信开发之自定义菜单完整流程
2016/10/08 PHP
PHP开发中解决并发问题的几种实现方法分析
2017/11/13 PHP
Yii2框架视图(View)操作及Layout的使用方法分析
2019/05/27 PHP
js 使用form表单select类实现级联菜单效果
2012/12/19 Javascript
javascript 获取模态窗口的滚动位置代码
2013/08/06 Javascript
JS保留两位小数,多位小数的示例代码
2014/01/07 Javascript
js图片延迟技术一般的思路与示例
2014/03/20 Javascript
jquery 判断滚动条到达了底部和顶端的方法
2014/04/02 Javascript
HTML5使用DeviceOrientation实现摇一摇功能
2015/06/05 Javascript
JQuery在循环中绑定事件的问题详解
2016/06/02 Javascript
JavaScript编写棋盘覆盖代码详解
2017/08/28 Javascript
浅谈react-native热更新react-native-pushy集成遇到的问题
2017/09/30 Javascript
关于Vue单页面骨架屏实践记录
2017/12/13 Javascript
angularjs实现分页和搜索功能
2018/01/03 Javascript
在Angular中实现一个级联效果的下拉框的示例代码
2020/05/20 Javascript
[46:16]2018DOTA2亚洲邀请赛3月30日 小组赛B组 iG VS VP
2018/03/31 DOTA
解决python写的windows服务不能启动的问题
2014/04/15 Python
通过实例浅析Python对比C语言的编程思想差异
2015/08/30 Python
Linux 发邮件磁盘空间监控(python)
2016/04/23 Python
python如何删除文件中重复的字段
2019/07/16 Python
python实现的汉诺塔算法示例
2019/10/23 Python
python实现udp聊天窗口
2020/03/31 Python
基于PyQT实现区分左键双击和单击
2020/05/19 Python
Django生成数据库及添加用户报错解决方案
2020/10/09 Python
Linux内核产生并发的原因
2012/07/13 面试题
培训主管的职业生涯规划
2014/03/06 职场文书
公司授权委托书
2014/04/04 职场文书
不遵守课堂纪律的检讨书
2014/09/24 职场文书
经理助理岗位职责
2015/02/02 职场文书
合理化建议书
2015/02/04 职场文书
golang 实现并发求和
2021/05/08 Golang
2022年显卡天梯图(6月更新)
2022/06/17 数码科技