试图学习递归函数,但无法绕过它

Dan*_*Dan 8 javascript recursion

我正在尝试学习如何使用递归函数,但我不了解发生了什么.

function power(base, exponent) {
    return base * power(base, exponent - 1);
};

alert(power(4,4));
Run Code Online (Sandbox Code Playgroud)

我越来越:

RangeError:超出最大调用堆栈大小.

从我要离开的例子来看,它有:

function power(base, exponent) {
  if (exponent == 0)
    return 1;
  else
    return base * power(base, exponent - 1);
}

alert(power(4,4));
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释为什么需要if语句吗?我怀疑我错过了什么.

pim*_*vdb 8

递归函数调用自身.这就是它的定义.

这带来了一个问题:它将无限期地调用自己.所以它将永远存在,这就是为什么你得到堆栈溢出.

相反,你应该停在某一点上.这是该if子句的用武之地.何时exponent == 0,您不调用该函数,而是停止该过程.

所以当执行power(3, 3)它时会像:

   power(3, 3) is equal to:

   3 * power(3, 2)
or 3 * 3 * power(3, 1)
or 3 * 3 * 3 * power(3, 0)
or 3 * 3 * 3 * 1            // no additional calls anymore; can be calculated now
Run Code Online (Sandbox Code Playgroud)

从一个不同的角度看:

  • power(4, 4)4 * power(4, 3)由函数定义 .
  • power(4, 3)4 * power(4, 2)由函数定义 .
  • power(4, 2)4 * power(4, 1)由函数定义 .
  • power(4, 1)4 * power(4, 0)由函数定义 .
  • power(4, 0)1由函数定义 .

如果您将所有内容替换为前一个,您将获得:

                         power(4, 4)
equals               4 * power(4, 3)
equals           4 * 4 * power(4, 2)
equals       4 * 4 * 4 * power(4, 1)
equals   4 * 4 * 4 * 4 * power(4, 0)
equals   4 * 4 * 4 * 4 *      1   
equals   256
Run Code Online (Sandbox Code Playgroud)


spi*_*ike 5

在递归中需要一个基本案例,以便它停止调用自身.在这种情况下,幂函数被永远调用(好吧,直到javascript解释器放弃),因为指数变为负无穷大.