前提
阶乘公式如下:
转公式为代码
“看图写话”
const f = (n) => n === 0? 1: n * f(n-1)
递归带来的麻烦(二)
我们需要先了解一个词儿栈溢出。
场景**:当执行的函数还没有结束就要进入下一个函数时,需要将当前的“现场”进行保存,另一个函数调用完毕之后,再回到“现场”继续执行。
以f(5)为例,f(5)会返回5f(4),f(4)在执行的时候会被5放到调用栈(调用栈就是上面提到的“现场”,放入过程叫压栈),嵌套的函数执行完毕后,继续将调用栈的“现场”弹出来完成运算(弹出的过程叫弹栈或出栈)。
现象**:然而,每个浏览器对于调用栈的长度都是长度限制的,长度过长就会导致浏览器崩溃、调用栈爆栈(也就是栈溢出)。
更具体一点:
(根据我实际在chrome调用,最下面为调用f(5)时的匿名函数)
我们可以通过以下代码测试一下不同浏览器所支持的调用栈的最大长度:
const computedMaxCallStack = () => {try{return 1 + computedMaxCallStack()} catch() {// 到达这里说明爆栈了return 1;}}
大部分的情况,调用栈是够用的,但墨粉定律告诉我们 —— 小概率的事情必然发生。
下一部分我们开始介绍: 如何减少压栈。
