详解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 构造函数 实例分析
Nov 26 Javascript
使用jQuery的ajax功能实现的RSS Reader 代码
Sep 03 Javascript
基于jquery实现一张图片点击鼠标放大再点缩小
Sep 29 Javascript
js实现类似菜单风格的TAB选项卡效果代码
Aug 28 Javascript
在Html中使用Requirejs进行模块化开发实例详解
Apr 15 Javascript
javascript 利用arguments实现可变长参数
Nov 21 Javascript
VUE中使用Vue-resource完成交互
Jul 21 Javascript
jquery插件开发之选项卡制作详解
Aug 30 jQuery
Vue中 key keep-alive的实现原理
Sep 18 Javascript
jQuery实现可编辑的表格
Dec 11 jQuery
使用vue编写h5公众号跳转小程序的实现代码
Nov 27 Vue.js
vue项目支付功能代码详解
Feb 18 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采集内容中带有图片地址的远程图片并保存的方法
2015/01/03 PHP
PHP实现图片不变型裁剪及图片按比例裁剪的方法
2016/01/14 PHP
Thinkphp整合微信支付功能
2016/12/14 PHP
用 JavaScript 迁移目录
2006/12/18 Javascript
使用jQuery清空file文件域的解决方案
2013/04/12 Javascript
使用CSS和jQuery模拟select并附提交后取得数据的代码
2013/10/18 Javascript
JS实现自定义简单网页软键盘效果代码
2015/11/05 Javascript
基于jQuery实现音乐播放试听列表
2016/04/14 Javascript
jquery简单插件制作(fn.extend)完整实例
2016/05/24 Javascript
js验证真实姓名与身份证号,手机号的简单实例
2016/07/18 Javascript
jQuery 自定义下拉框(DropDown)附源码下载
2016/07/22 Javascript
Bootstrap CSS组件之导航条(navbar)
2016/12/17 Javascript
JavaScript实现二叉树定义、遍历及查找的方法详解
2017/12/20 Javascript
vue2.0 + element UI 中 el-table 数据导出Excel的方法
2018/03/02 Javascript
使用Angular CLI生成路由的方法
2018/03/24 Javascript
jquery使用FormData实现异步上传文件
2018/10/25 jQuery
详解小程序设置缓存并且不覆盖原有数据
2019/04/15 Javascript
微信接入之获取用户头像的方法步骤
2019/09/23 Javascript
微信小程序之左右布局的实现代码
2019/12/13 Javascript
查找Vue中下标的操作(some和findindex)
2020/08/12 Javascript
[13:39]2014 DOTA2华西杯精英邀请赛 5 25 NewBee VS DK第一场
2014/05/26 DOTA
[36:33]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.29
2020/12/02 DOTA
Python中用Spark模块的使用教程
2015/04/13 Python
python实现多线程行情抓取工具的方法
2018/02/28 Python
python3 unicode列表转换为中文的实例
2018/10/26 Python
python 读写文件包含多种编码格式的解决方式
2019/12/20 Python
几款Python编译器比较与推荐(小结)
2020/10/15 Python
利用CSS3把图片变成灰色模式的实例代码
2016/09/06 HTML / CSS
HTML5的语法变化介绍
2013/08/13 HTML / CSS
数据库测试通常都包括哪些方面
2015/11/30 面试题
董事长岗位职责
2013/11/30 职场文书
保护动物的标语
2014/06/11 职场文书
武夷山导游词
2015/02/03 职场文书
信息技术国培研修日志
2015/11/13 职场文书
学习型家庭事迹材料(2016精选版)
2016/02/29 职场文书
5个实用的JavaScript新特性
2022/06/16 Javascript