详解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 相关文章推荐
ASP.NET jQuery 实例6 (实现CheckBoxList成员全选或全取消)
Jan 13 Javascript
JS弹出窗口代码大全(详细整理)
Dec 21 Javascript
JQuery EasyUI 数字格式化处理示例
May 05 Javascript
js调试系列 控制台命令行API使用方法
Jun 18 Javascript
封装好的javascript前端分页插件pagination
Jan 04 Javascript
AngularJS中的指令全面解析(必看)
May 20 Javascript
详解js中call与apply关键字的作用
Nov 21 Javascript
Jquery根据浏览器窗口改变调整大小的方法
Feb 07 Javascript
angularjs实现上拉加载和下拉刷新数据功能
Jun 12 Javascript
ES6中数组array新增方法实例总结
Nov 07 Javascript
jQuery实现获取form表单内容及绑定数据到form表单操作分析
Jul 03 jQuery
微信小程序实现签到弹窗动画
Sep 21 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
thinkphp中AJAX返回ajaxReturn()方法分析
2016/12/06 PHP
Laravel下生成验证码的类
2017/11/15 PHP
ThinkPHP3.2框架自带分页功能实现方法示例
2019/05/13 PHP
JS 获取span标签中的值的代码 支持ie与firefox
2009/08/24 Javascript
JS获取几种URL地址的方法小结
2014/02/26 Javascript
多个jQuery版本共存的处理方案
2015/03/17 Javascript
javascript HTML+CSS实现经典橙色导航菜单
2016/02/16 Javascript
简单的js表格操作
2016/09/24 Javascript
详解Jquery 遍历数组之$().each方法与$.each()方法介绍
2017/01/09 Javascript
BootStrap daterangepicker 双日历控件
2017/06/02 Javascript
ionic2懒加载配置详解
2017/09/01 Javascript
VueJS事件处理器v-on的使用方法
2017/09/27 Javascript
详细分析单线程JS执行问题
2017/11/22 Javascript
详解基于Vue cli生成的Vue项目的webpack4升级
2018/06/19 Javascript
在iFrame子页面里实现模态框的方法
2018/08/17 Javascript
react 父子组件之间通讯props
2018/09/08 Javascript
浅谈Vue.js之初始化el以及数据的绑定说明
2019/11/14 Javascript
JavaScript实现电灯开关小案例
2020/03/30 Javascript
js实现直播点击飘心效果
2020/08/19 Javascript
Node.js文本文件BOM头的去除方法
2020/11/22 Javascript
python ip正则式
2009/05/07 Python
Python对文件和目录进行操作的方法(file对象/os/os.path/shutil 模块)
2017/05/08 Python
python实现log日志的示例代码
2018/04/28 Python
python3使用flask编写注册post接口的方法
2018/12/28 Python
python3编写ThinkPHP命令执行Getshell的方法
2019/02/26 Python
Django中如何使用sass的方法步骤
2019/07/09 Python
Python代码执行时间测量模块timeit用法解析
2020/07/01 Python
解决python便携版无法直接运行py文件的问题
2020/09/01 Python
Python批量删除mysql中千万级大量数据的脚本分享
2020/12/03 Python
优秀的自荐信要注意哪些
2014/01/03 职场文书
大学竞选班干部演讲稿
2014/08/21 职场文书
法定代表人身份证明书(含说明)
2014/10/02 职场文书
公证书
2019/04/17 职场文书
SqlServer 垂直分表(减少程序改动)
2021/04/16 SQL Server
Python Pandas pandas.read_sql函数实例用法
2021/06/21 Python
电频谱管理的原则是什么
2022/02/18 无线电