详解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实现单击按钮遮罩弹出对话框(仿天猫的删除对话框)
Apr 10 Javascript
js中javascript:void(0) 真正含义
Nov 05 Javascript
jquery ajax双击div可直接修改div中的内容
Mar 04 Javascript
Javascript之Number对象介绍
Jun 07 Javascript
JQuery遍历元素的后代和同胞实现方法
Sep 18 Javascript
Bootstrap如何创建表单
Oct 21 Javascript
实例详解BootStrap的动态模态框及静态模态框
Aug 13 Javascript
vue2.0 element-ui中el-select选择器无法显示选中的内容(解决方法)
Aug 24 Javascript
微信小程序保存多张图片的实现方法
Mar 05 Javascript
Angular7中创建组件/自定义指令/管道的方法实例详解
Apr 02 Javascript
Element Tooltip 文字提示的使用示例
Jul 26 Javascript
javascript中正则表达式语法详解
Aug 07 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 MemCached 高级缓存应用代码
2010/08/05 PHP
php支付宝接口用法分析
2015/01/04 PHP
php生成过去100年下拉列表的方法
2015/07/20 PHP
Zend Framework动作助手Json用法实例分析
2016/03/05 PHP
phpStudy2016 配置多个域名期间遇到的问题小结
2017/10/19 PHP
浅谈PHP匿名函数和闭包
2019/03/08 PHP
PHP中单例模式的使用场景与使用方法讲解
2019/03/18 PHP
浅谈laravel中的关联查询with的问题
2019/10/10 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
2020/04/05 PHP
jquery 学习笔记一
2010/04/07 Javascript
再谈javascript原型继承
2014/11/10 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
2015/03/18 Javascript
原生js实现的贪吃蛇网页版游戏完整实例
2015/05/18 Javascript
js限制input标签中只能输入中文
2015/06/26 Javascript
js实现的Easy Tabs选项卡用法实例
2015/09/06 Javascript
jQuery图片轮播滚动切换代码分享
2020/04/20 Javascript
javascript生成img标签的3种实现方法(对象、方法、html)
2015/12/25 Javascript
JS实现星星评分功能实例代码(两种方法)
2016/06/09 Javascript
jQuery实现的电子时钟效果完整示例
2018/04/28 jQuery
Vue唯一可以更改vuex实例中state数据状态的属性对象Mutation的讲解
2019/01/18 Javascript
extjs图形绘制之饼图实现方法分析
2020/03/06 Javascript
JS面向对象实现飞机大战
2020/08/26 Javascript
python xml.etree.ElementTree遍历xml所有节点实例详解
2016/12/04 Python
python 数据清洗之数据合并、转换、过滤、排序
2017/02/12 Python
详解python实现读取邮件数据并下载附件的实例
2017/08/03 Python
取numpy数组的某几行某几列方法
2018/04/03 Python
python实现将列表中各个值快速赋值给多个变量
2020/04/02 Python
HTML5里autofocus自动聚焦属性使用介绍
2016/06/22 HTML / CSS
介绍Java的内部类
2012/10/27 面试题
餐厅执行经理岗位职责范本
2014/02/26 职场文书
2015年毕业生自我鉴定模板
2014/09/19 职场文书
大学生实习推荐信
2015/03/27 职场文书
2015年计算机教师工作总结
2015/07/22 职场文书
师德师风心得体会(2016精选篇)
2016/01/12 职场文书
ObjectMapper 如何忽略字段大小写
2021/06/29 Java/Android
前端使用svg图片改色实现示例
2022/07/23 HTML / CSS