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 相关文章推荐
JS+CSS实现经典的左侧竖向滑动菜单效果
Sep 23 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖放商品放置购物车
Nov 30 Javascript
轻松学习Javascript闭包函数
Dec 15 Javascript
JavaScript通过使用onerror设置默认图像显示代替alt
Mar 01 Javascript
JS实现重新加载当前页面
Nov 29 Javascript
jquery DataTable实现前后台动态分页
Jun 17 jQuery
详解使用vue实现tab 切换操作
Jul 03 Javascript
Vue.js组件高级特性实例详解
Dec 24 Javascript
react组件从搭建脚手架到在npm发布的步骤实现
Jan 09 Javascript
关于layui导航栏不展示下拉列表的解决方法
Sep 25 Javascript
jQuery实现雪花飘落效果
Aug 02 jQuery
JavaScript实现轮播图效果
Oct 30 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 简单日历实现代码
2009/10/28 PHP
PHP foreach循环使用详解与实例代码
2010/05/08 PHP
基于PHP常用函数的用法详解
2013/05/10 PHP
PHP中使用register_shutdown_function函数截获fatal error示例
2015/04/21 PHP
一个基于jquery的图片切换效果
2010/07/06 Javascript
javascript onmouseout 解决办法
2010/07/17 Javascript
Jquery getJSON方法详细分析
2013/12/26 Javascript
浅谈jQuery中的checkbox问题
2016/08/10 Javascript
浅谈angular2的http请求返回结果的subcribe注意事项
2017/03/01 Javascript
Angular5.1新功能分享
2017/12/21 Javascript
JavaScript使用ul中li标签实现删除效果
2019/04/15 Javascript
解决vue组件props传值对象获取不到的问题
2019/06/06 Javascript
vue实现滑动超出指定距离回顶部功能
2019/07/31 Javascript
微信小程序实现点击导航标签滚动定位到对应位置
2020/11/19 Javascript
一文秒懂nodejs中的异步编程
2021/01/28 NodeJs
跟老齐学Python之私有函数和专有方法
2014/10/24 Python
Python利用Beautiful Soup模块修改内容方法示例
2017/03/27 Python
Python3使用正则表达式爬取内涵段子示例
2018/04/22 Python
Python字符串的一些操作方法总结
2019/06/10 Python
Python使用python-docx读写word文档
2019/08/26 Python
python实现五子棋程序
2020/04/24 Python
Tensorflow tf.tile()的用法实例分析
2020/05/22 Python
Python爬虫爬取新闻资讯案例详解
2020/07/14 Python
推荐值得学习的12款python-web开发框架
2020/08/10 Python
巴西购物网站:Estrela10
2018/12/13 全球购物
Oakley西班牙官方商店:太阳眼镜和男女运动服
2019/04/26 全球购物
C&A巴西网上商店:时尚、衣服、手机和鞋子
2020/06/07 全球购物
造型师求职自荐信
2013/09/27 职场文书
公务员的自我鉴定
2013/10/26 职场文书
学生会干部自荐信
2014/02/04 职场文书
护士求职自荐信范文
2014/03/19 职场文书
《乡下孩子》教学反思
2014/04/17 职场文书
自主招生教师推荐信
2014/05/10 职场文书
求职导师推荐信范文
2015/03/27 职场文书
Html5生成验证码的示例代码
2021/05/10 Javascript
Python创建SQL数据库流程逐步讲解
2022/09/23 Python