详解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的关于动态创建DOM元素的问题
Dec 24 Javascript
关于jquery性能最佳实践的讨论,与求教
Mar 30 Javascript
js与jquery实时监听输入框值的oninput与onpropertychange方法
Feb 05 Javascript
浅谈js中的闭包
Mar 16 Javascript
JavaScript中常见的字符串操作函数及用法汇总
May 04 Javascript
原生js获取元素样式的简单方法
Aug 06 Javascript
AngularJS使用自定义指令替代ng-repeat的方法
Sep 17 Javascript
AngularJS实现表格的增删改查(仅限前端)
Jul 04 Javascript
VUE axios发送跨域请求需要注意的问题
Jul 06 Javascript
基于JavaScript中标识符的命名规则介绍
Jan 06 Javascript
Less 安装及基本用法
May 05 Javascript
VUE前端从后台请求过来的数据进行转换数据结构操作
Nov 11 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 fread()使用技巧
2010/01/22 PHP
PHP怎么实现网站保存快捷方式方便用户随时浏览
2013/08/15 PHP
WordPress自定义时间显示格式
2015/03/27 PHP
Yii统计不同类型邮箱数量的方法
2016/10/18 PHP
PHP实现八皇后算法
2019/05/06 PHP
php的扩展写法总结
2019/05/14 PHP
laravel框架模型、视图与控制器简单操作示例
2019/10/10 PHP
php获取是星期几的的一些常用姿势
2019/12/15 PHP
ThinkPHP5分页paginate代码实例解析
2020/11/10 PHP
权威JavaScript 中的内存泄露模式
2007/08/13 Javascript
Javascript !!的作用
2008/12/04 Javascript
jquery动画3.创建一个带遮罩效果的图片走廊
2012/08/24 Javascript
关于jquery input textare 事件绑定及用法学习
2013/04/03 Javascript
js中同步与异步处理的方法和区别总结
2013/12/25 Javascript
jQuery对下拉框,单选框,多选框的操作
2014/02/21 Javascript
jQuery实现平滑滚动页面到指定锚点链接的方法
2015/07/15 Javascript
解决jquery中动态新增的元素节点无法触发事件问题的两种方法
2015/10/30 Javascript
Vue3 源码导读(推荐)
2019/10/14 Javascript
Vue 如何使用props、emit实现自定义双向绑定的实现
2020/06/05 Javascript
Map与WeakMap类型在JavaScript中的使用详解
2020/11/18 Javascript
[02:38]DOTA2 夜魇暗潮2020活动介绍官方视频
2020/11/04 DOTA
Python使用urllib模块的urlopen超时问题解决方法
2014/11/08 Python
Python设计模式之状态模式原理与用法详解
2019/01/15 Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
2019/03/30 Python
Python 正则表达式爬虫使用案例解析
2019/09/23 Python
超实用的 30 段 Python 案例
2019/10/10 Python
基于TensorFlow的CNN实现Mnist手写数字识别
2020/06/17 Python
python3中for循环踩过的坑记录
2020/12/14 Python
HTML5页面音视频在微信和app下自动播放的实现方法
2016/10/20 HTML / CSS
JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
2013/07/02 面试题
毕业生求职自荐信怎么写
2014/01/08 职场文书
网络营销策划方案
2014/06/04 职场文书
婚礼嘉宾致辞
2015/07/28 职场文书
会议承办单位欢迎词
2015/09/30 职场文书
经销商会议开幕词
2016/03/04 职场文书
简述python四种分词工具,盘点哪个更好用?
2021/04/13 Python