为什么Eloquent JavaScript的这个函数示例返回值24?

时间:2014-12-21 23:50:10

标签: javascript function recursion

我是JavaScript的新手,我正在尝试理解本书中的一个例子。当我逐步完成这个例子时,我期望fac(4)的值为12.这将是(4 - 1)* 4的结果。

但是,当我在http://eloquentjavascript.net/00_intro.html处运行在线图书(靠近页面底部)的代码时,我得到的值为24.我在这里缺少什么?

function fac(n) {
  if (n == 0)
    return 1;
  else
    return fac(n - 1) * n;
}
console.log(fac(4));

我试图通过Twitter和在线研究找到答案,但一直没有成功。我知道我忽略了什么,但似乎无法看到它。

2 个答案:

答案 0 :(得分:4)

因为它是递归的。

function fac(n) {
  if (n == 0)
    return 1;
  else
    return fac(n - 1) * n;
}
console.log(fac(4));

所以让我们追踪它

fac(3) * 4;
fac(2) * 3 * 4;
fac(1) * 2 * 3 * 4;
fac(0) * 1 * 2 * 3 * 4;
1 * 1 * 2 * 3 * 4;

当然,那是24岁。

答案 1 :(得分:3)

如果你注意到你的代码,那么在第5行,这个函数就是自己调用,这叫做递归,在wikipedia

上阅读更多相关信息。

让我们回到你的代码并干掉它以查看它是如何工作的。让我们给每一行一个数字,以便我们可以参考

1.function fac(n) {
2.  if (n == 0)
3.    return 1;
4.  else
5.    return fac(n - 1) * n;
6.}
7.console.log(fac(4));

首次通话时您的输入值为4,我们可以将其称为call A

对于第4行的值if条件将返回false,因此它将转到第5行再次调用

fac(3) * 4;

现在,您的函数call A暂停,并生成值{3} call Bcall A的结果尚待评估。

现在值为3,第2行的if条件将再次返回false,第5行的代码将执行如上所述;即

fac(2) * 3;

call B在此处暂停,call C将显示相同功能的输入2。

call C上,您的代码会在第2行针对false条件返回if,因此会在输入1时生成call D,即

fac(1) * 2

对于call D if条件,第2行将返回true,并且您的函数将返回1,以便call D以值1进行评估。现在从底部替换每个fac(n)顶部并继续评估每个电话。

result of call D => 1  
result of call C => fac(1) * 2 => 1 * 2 => 2  
result of call B => fac(2) * 3 => 2 * 3 => 6  
result of call A => fac(3) * 4 => 6 * 4 => 24

我希望你能够理解它是如何工作的,递归的重点是你在第2行编码的停止条件。

上面的结果也可以通过使用循环产生,但使用递归更有趣。

快乐编码:)