详解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 相关文章推荐
js prototype 格式化数字 By shawl.qiu
Apr 02 Javascript
jquery实现最简单的滑动菜单效果代码
Sep 12 Javascript
基于jQuery实现的美观星级评论打分组件代码
Oct 30 Javascript
node.js实现复制文本到剪切板的功能
Jan 23 Javascript
js排序与重组的实例讲解
Aug 28 Javascript
JS随机排序数组实现方法分析
Oct 11 Javascript
Bootstrap 模态框多次显示后台提交多次BUG的解决方法
Dec 26 Javascript
animate.css在vue项目中的使用教程
Aug 05 Javascript
Vue配置marked链接添加target="_blank"的方法
Jul 19 Javascript
TypeScript高级用法的知识点汇总
Dec 17 Javascript
通过微信公众平台获取公众号文章的方法示例
Dec 25 Javascript
返回上一个url并刷新界面的js代码
Sep 12 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
PHP静态类
2006/11/25 PHP
php中文本操作的类
2007/03/17 PHP
php socket方式提交的post详解
2008/07/19 PHP
基于PHP的cURL快速入门教程 (小偷采集程序)
2011/06/02 PHP
洪恩在线成语词典小偷程序php版
2012/04/20 PHP
Zend的MVC机制使用分析(一)
2013/05/02 PHP
php实现图片上传、剪切功能
2016/05/07 PHP
PHP实现的装箱算法示例
2018/06/23 PHP
针对PHP开发安全问题的相关总结
2019/03/22 PHP
获取Javscript执行函数名称的方法
2006/12/22 Javascript
jQuery的.live()和.die() 使用介绍
2011/09/10 Javascript
JQuery插件开发示例代码
2013/11/06 Javascript
多引号嵌套的变量命名的问题
2014/05/09 Javascript
jquery中post方法用法实例
2014/10/21 Javascript
node.js中的http.request.end方法使用说明
2014/12/10 Javascript
javascript基于DOM实现省市级联下拉框的方法
2015/05/14 Javascript
无刷新上传文件并返回自定义值
2015/06/11 Javascript
深入理解Javascript箭头函数中的this
2017/02/13 Javascript
bootstrap基本配置_动力节点Java学院整理
2017/07/14 Javascript
原生实现一个react-redux的代码示例
2018/06/08 Javascript
解决vue-cli3 使用子目录部署问题
2018/07/19 Javascript
微信小程序中使用echarts的实现方法
2019/04/24 Javascript
实现elementUI表单的全局验证的方法步骤
2019/04/29 Javascript
微信小程序HTTP请求从0到1封装
2019/09/09 Javascript
Python while、for、生成器、列表推导等语句的执行效率测试
2015/06/03 Python
python贪婪匹配以及多行匹配的实例讲解
2018/04/19 Python
python批量赋值操作实例
2018/10/22 Python
python实现多进程代码示例
2018/10/31 Python
python使用Matplotlib改变坐标轴的默认位置
2019/10/18 Python
Python打包模块wheel的使用方法与将python包发布到PyPI的方法详解
2020/02/12 Python
Python unittest如何生成HTMLTestRunner模块
2020/09/08 Python
什么是方法的重载
2013/06/24 面试题
自我鉴定200字
2013/10/28 职场文书
党员作风建设自查报告
2014/10/23 职场文书
学生会自荐信
2019/05/16 职场文书
PYTHON基于Pyecharts绘制常见的直角坐标系图表
2022/04/28 Python