详解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 相关文章推荐
jQuery 使用手册(七)
Sep 23 Javascript
用js编写的简单的计算器代码程序
Aug 04 Javascript
高性能JavaScript循环语句和条件语句
Jan 20 Javascript
分享自己用JS做的扫雷小游戏
Feb 17 Javascript
JS在onclientclick里如何控制onclick的执行
May 30 Javascript
js判断iframe中元素是否存在的实现代码
Dec 24 Javascript
JS调用Android、Ios原生控件
Jan 06 Javascript
基于Bootstrap 3 JQuery及RegExp的表单验证功能
Feb 16 Javascript
jQuery插件FusionCharts绘制的2D条状图效果【附demo源码】
May 13 jQuery
Vue.js 使用v-cloak后仍显示变量的解决方法
Nov 19 Javascript
微信小程序如何获取地址
Dec 24 Javascript
Element InputNumber 计数器的实现示例
Aug 03 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实现SAE上使用storage上传与下载文件的方法
2015/06/29 PHP
Laravel框架创建路由的方法详解
2019/09/04 PHP
javascript对象的property和prototype是这样一种关系
2007/03/24 Javascript
用CSS+JS实现的进度条效果效果
2007/06/05 Javascript
checkbox 复选框不能为空
2009/07/11 Javascript
js页面跳转常用的几种方式
2010/11/25 Javascript
JavaScript中:表达式和语句的区别[译]
2012/09/17 Javascript
提高NodeJS中SSL服务的性能
2014/07/15 NodeJs
函数window.open实现关闭所有的子窗口
2015/08/03 Javascript
js获取新浪天气接口的实现代码
2016/06/06 Javascript
AngularJs  unit-testing(单元测试)详解
2016/09/02 Javascript
深入浅出webpack教程系列_安装与基本打包用法和命令参数详解
2017/09/10 Javascript
JS实现的简单标签点击切换功能示例
2017/09/21 Javascript
利用vue+elementUI实现部分引入组件的方法详解
2017/11/22 Javascript
vue axios 表单提交上传图片的实例
2018/03/16 Javascript
vue-cli3搭建项目的详细步骤
2018/12/05 Javascript
vue项目设置scrollTop不起作用(总结)
2018/12/21 Javascript
详解vue-cli 脚手架 安装
2019/04/16 Javascript
nodejs搭建本地服务器并访问文件操作示例
2019/05/11 NodeJs
利用Electron简单撸一个Markdown编辑器的方法
2019/06/10 Javascript
javascript操作元素的常见方法小结
2019/11/13 Javascript
跟老齐学Python之玩转字符串(3)
2014/09/14 Python
Python模块文件结构代码详解
2018/02/03 Python
python生成tensorflow输入输出的图像格式的方法
2018/02/12 Python
Python根据欧拉角求旋转矩阵的实例
2019/01/28 Python
使用django的objects.filter()方法匹配多个关键字的方法
2019/07/18 Python
python之语音识别speech模块
2020/09/09 Python
HTML5+CSS3实现拖放(Drag and Drop)示例
2014/07/07 HTML / CSS
canvas生成带二维码海报的踩坑记录
2019/09/11 HTML / CSS
美国女士泳装店:Swimsuits For All
2017/03/02 全球购物
西班牙在线宠物食品和配件商店:bitiba
2019/10/11 全球购物
送餐员岗位职责范本
2014/02/21 职场文书
恶搞卫生巾广告词
2014/03/18 职场文书
妇联领导班子剖析材料
2014/08/21 职场文书
党员干部群众路线个人整改措施
2014/09/18 职场文书
董事长开业致辞
2015/07/29 职场文书