JS的函数调用栈stack size的计算方法


Posted in Javascript onJune 24, 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 相关文章推荐
用Javascript实现UTF8编码转换成gb2312编码
Dec 22 Javascript
利用404错误页面实现UrlRewrite的实现代码
Aug 20 Javascript
JavaScript与DropDownList 区别分析
Jan 01 Javascript
JavaScript模板入门介绍
Sep 26 Javascript
jQuery使用数组编写图片无缝向左滚动
Dec 11 Javascript
完美解决AJAX跨域问题
Nov 01 Javascript
jquery实现的淡入淡出下拉菜单效果
Aug 25 Javascript
JS组件Bootstrap Select2使用方法详解
Apr 17 Javascript
微信小程序  TLS 版本必须大于等于1.2问题解决
Feb 22 Javascript
layui操作列按钮个数和文字颜色的判断实例
Sep 11 Javascript
解决antd Form 表单校验方法无响应的问题
Oct 27 Javascript
JavaScript中10个Reduce常用场景技巧
Jun 21 Javascript
JavaScript中var、let、const区别浅析
Jun 24 #Javascript
使用JavaScript中的lodash编写双色球效果
Jun 24 #Javascript
Vue中$refs的用法详解
Jun 24 #Javascript
JS实现获取word文档内容并输出显示到html页面示例
Jun 23 #Javascript
纯JS实现的读取excel文件内容功能示例【支持所有浏览器】
Jun 23 #Javascript
Vue子组件向父组件通信与父组件调用子组件中的方法
Jun 22 #Javascript
Vue验证码60秒倒计时功能简单实例代码
Jun 22 #Javascript
You might like
PHP在字符断点处截断文字的实现代码
2011/04/21 PHP
php遍历目录与文件夹的多种方法详解
2013/11/14 PHP
php防止网站被刷新的方法汇总
2014/12/01 PHP
php遍历替换目录下文件指定内容的方法
2016/11/10 PHP
PHP new static 和 new self详解
2017/02/19 PHP
基于jquery & json的省市区联动代码
2012/06/26 Javascript
js确认删除对话框效果的示例代码
2014/02/20 Javascript
javascript新闻跑马灯实例代码
2020/07/29 Javascript
对javascript继承的理解
2016/10/11 Javascript
Ajax 加载数据 练习代码
2017/01/05 Javascript
使用Bootrap和Vue实现仿百度搜索功能
2017/10/26 Javascript
使用jquery的cookie实现登录页记住用户名和密码的方法
2019/03/13 jQuery
[00:48]完美“圣”典2016风云人物:xiao8宣传片
2016/11/30 DOTA
[36:09]Secret vs VG 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.24
2019/09/10 DOTA
wxpython 学习笔记 第一天
2009/03/16 Python
Python httplib模块使用实例
2015/04/11 Python
python在Windows下安装setuptools(easy_install工具)步骤详解
2016/07/01 Python
python 删除字符串中连续多个空格并保留一个的方法
2018/12/22 Python
python自动发邮件总结及实例说明【推荐】
2019/05/31 Python
python爬虫 2019中国好声音评论爬取过程解析
2019/08/26 Python
浅谈keras中的keras.utils.to_categorical用法
2020/07/02 Python
利用PyQt5+Matplotlib 绘制静态/动态图的实现代码
2020/07/13 Python
matplotlib绘制鼠标的十字光标的实现(内置方式)
2021/01/06 Python
Under Armour澳大利亚官网:美国知名的高端功能性运动品牌
2018/02/22 全球购物
Boom手表官网:瑞典手表品牌,设计你的手表
2019/03/11 全球购物
解释一下Windows的消息机制
2014/01/30 面试题
工伤事故赔偿协议书
2014/04/15 职场文书
希特勒经典演讲稿
2014/05/19 职场文书
汽车销售经理岗位职责
2014/06/09 职场文书
雷锋式好少年事迹材料
2014/08/17 职场文书
小学班主任个人总结
2015/03/03 职场文书
2015年城管个人工作总结
2015/05/15 职场文书
《我的长生果》教学反思
2016/02/20 职场文书
咖啡厅里的创业计划书
2019/08/21 职场文书
PostgreSQL解析URL的方法
2021/08/02 PostgreSQL
nginx 配置指令之location使用详解
2022/05/25 Servers