雄辩的JavaScript:无法理解递归的例子

时间:2015-08-16 16:43:22

标签: javascript

来自Haverbeke第二版的第50页。我添加了几个console.log来试图更好地跟踪进度。

function power(base, exponent) {
  if (exponent == 0) {
    console.log("line 5 " + base + "  " + exponent); 
    return 1;
  }
  else
    console.log("line 10 " + base + "  " + exponent);
    return base * power(base, exponent -1);
}
console.log(power(2,3));

//输出

line 10 2  3

line 10 2  2

line 10 2  1

line 5 2  0

8

//

我希望最终输出为1,因为当if (exponent == 0)为真时,下一个语句为return 1;,但它似乎再次输入else返回8.但return不应该让我们离开这个职能部门。

显然是一个新手,或者不会被困在一本据称是初学者书的第50页。

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

每当函数进入“else”分支时,都会创建一个新的堆栈帧,等待递归调用的结果。您可以逐步想象评估:

  1. power(2, 3)进入else分支,然后返回base * power(base, exponent - 1)

  2. 2 * power (2, 2)进入else分支,然后返回base * power(base, exponent - 1)

  3. 2 * (2 * power (2, 1))进入else分支,然后返回base * power(base, exponent - 1)

  4. 2 * (2 * (2 * power (2, 0)))进入if分支,然后返回1

  5. 您最终可以评估结果:2 * (2 * (2 * 1)),即8

答案 1 :(得分:2)

函数调用power(2,3)的最终结果不是最后一次返回,而是后续内部函数调用返回值的组合。让我们解构递归函数:

  • power(2,3)返回2 * power(2,2)
  • power(2,2)返回2 * power(2,1)
  • power(2,1)返回2 * power(2,0)
  • power(2,0)返回1

总的来说,power(2,3)会返回2 * 2 * 2 * 1,等于8

答案 2 :(得分:1)

return语句退出函数的一次调用。为了到达return 1;行,该函数将被多次调用(基于指数的原始值)。

第一次调用是

console.log(power(2,3));

在函数内部,后续调用发生在这里:

    return base * power(base, exponent -1);

每个人都会对应return

哦,正如@TJCrowder在评论中指出的那样,该代码不正确:else部分应该包含在{ }中:

if (exponent == 0) {
  console.log("line 5 " + base + "  " + exponent); 
  return 1;
}
else {
  console.log("line 10 " + base + "  " + exponent);
  return base * power(base, exponent -1);
}

我假设丢失的{ }包装器是转录错误。