JS的函数调用栈有多深?

译者按: 有时候会遇到Maximum call stack size exceeded的问题,本文教你stack size的计算方法。

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。

如果你写了一个一直调用自身的死循环,那么恭喜你,很快就可以看到报错: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(); };}());

关于Fundebug

Fundebug专注于JavaScript、微信小程序、小游戏BUG监控,自从2016年双十一正式上线,Fundebug已经服务了一年半时间,累计处理了5亿+错误事件,得到了众多知名用户的认可。Fundebug支持主流前端框架的bug监控,欢迎各位老铁体验!

原文链接:http://2ality.com/2014/04/call-stack-size.html

原文作者:Dr. Axel Rauschmayer

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大闲人柴毛毛

使用Eclipse插件提高Java编码质量

代码质量概述 ? 怎样辨别一个项目代码写得好还是坏?优秀的代码和腐化的代码区别在哪里?怎么让自己写的代码既漂亮又有生命力?接下来将对代码质量的问题进行...

2867
来自专栏Keegan小钢

App架构经验总结(一)

原文链接:http://keeganlee.me/post/architecture/20160303 版权声明:本文刊载在《程序员》杂志2016年3期,版权归...

1354
来自专栏java一日一条

怎样编写高质量的Java代码

怎样辨别一个项目代码写得好还是坏?优秀的代码和腐化的代码区别在哪里?怎么让自己写的代码既漂亮又有生命力?接下来将对代码质量的问题进行一些粗略的介绍。也请有过代码...

741
来自专栏华章科技

Java 10新特性解密

请注意,本文中所包含的信息在写本文时是准确的。但是到发布时,JDK 10特性组预计将会增加。

592
来自专栏java学习

Java基础第一天学习笔记

01.01_计算机基础知识(计算机概述)(了解) * A:什么是计算机?计算机在生活中的应用举例 * 计算机(Computer)全称:电子计算机,俗称电脑。是...

3485
来自专栏Java技术分享圈

杨老师课堂_Java教程第一篇之认识计算机

*接下来就是确定、确定、确定就ok! *检验环境变量是否成功在DOS命令行里输入javac或java,如果正常显示一些内容,说明安装成功并且配...

692
来自专栏互联网杂技

前端面试题整理

交互设计前端开发 前言: 现在前端面试主要考察以下几个方面: 初级的:html、css、js,jquery,开发工具git的使用,对其他框架稍微了解; 中级的:...

4129
来自专栏Golang语言社区

golang websocket总结(问题贴)

因为工作的需要,接触了websocket,开始的一些很简单的代码,都不知道该怎样运行起来,所以,总是有一层神秘感,却没有太多的兴趣去研究它。不过,还是免不了要了...

3747
来自专栏Python爱好者

Java基础笔记01

1466
来自专栏大前端开发

从编程小白到全栈开发:理解异步

作为以JavaScript为主要开发语言的JS全栈开发者,是一定会碰上“异步(Asynchronous)”这个重要概念的,尽早的理解这个概念,会对你的JS编程生...

653

扫码关注云+社区