这个递归是如何工作的?

时间:2016-10-14 10:00:08

标签: javascript function recursion

现在我正在阅读MDN功能部分,我正在阅读这个关于递归的例子,其中包括:

    function foo(i) {
    if (i < 0)      //1
    return;
    console.log('begin:' + i);   //2
    foo(i - 1);   //3
    console.log('end:' + i); //4
}
foo(3);

所以我通常期望用参数3调用递归函数foo是它转到第1行检查开始时不会持有的条件因此它继续第2行并记录(&# 34;开始:3&#34;)然后它转到第3行,其中递归发生,这将使它返回到第1行并经历相同的流程流,这应该导致(&#34;开始:2& #34;),(&#34;开始:1&#34;),(&#34;开始:0&#34;),然后它应该停止,以便它不会阻塞(&#34;开始:-1&#34;),确实发生在MDN示例中,但不知何故它的日志再次出现,但可逆地如下:

// Output:

// begin:3
// begin:2
// begin:1
// begin:0
// end:0
// end:1
// end:2
// end:3

我的问题:

  1. 在那之后的意义上(i = -1)并且函数返回, 功能是否退出该功能并继续第4行?

  2. 如何(i)再次增加,我看不到循环或递归     再次增加(i)的值,使其再次从0记录到3 ??

5 个答案:

答案 0 :(得分:1)

以下是您的案例:

// foo(3) called
console.log('begin:3');
foo(2)
    console.log('begin:2');
    foo(1)
        console.log('begin:1');
        foo(0)
            console.log('begin:0');
            foo(-1)
                return;
            console.log('end:0');
        console.log('end:1');
    console.log('end:2');
console.log('end:3');

1)当你有(i == -1)时,该函数实际上是在返回时退出,但是后来继续在父函数中执行代码(见第2点))

2)当你调用foo(-1)时,你调用return,这意味着你回到你的父调用者并继续执行以下代码。

答案 1 :(得分:0)

你的函数在内部函数调用的结果出现之前没有终止。

1)是中止条件,它告诉函数何时停止

2)它没有增加,它更进一步,因为foo(i-1)调用的结果是那里

答案 2 :(得分:0)

每当发生递归时,控件始终保持在顶层。因此,虽然函数经过n个内部级别,但来自其中一个内部调用函数的return语句只会返回其直接父级别。

在这种情况下:i = 3处于顶层,然后是2然后是1然后是0.当返回在i = -1时触发时,它被冒泡回到其父级0。下一个回报将其冒泡到其父i = 2,然后i = 3.

如果您满意,请标记为答案。

答案 3 :(得分:0)

您的功能完全按照您的要求执行:

print begin:3
do everything that foo(3-1) does
print end:3

对函数的每次调用都等待它完成,然后才能恢复到下一行。如果它的功能相同,那么它是相同的。调用函数的版本不会与它调用的函数一起干预,因此它们是单独的,就像它们是单独的函数一样

想象一下这个功能:

function foo(i) {
    console.log('begin:' + i);  //1
    console.log('end:' + i);    //2
}

现在第一个console.log可能是一个递归函数。你不知道也不应该知道。它完成了它的工作和回报。你不会质疑它为什么继续排第二,所以我猜你给递归函数更加神秘,而不是它应得的。

答案 4 :(得分:0)

function foo(i) {
    if (i < 0){      //1
       return;
    }
    console.log('begin:' + i);   //2
       function foo(i-1) {
       if (i-1 < 0){      //3.3.1
          return;
       }
       console.log('begin:' + i-1-1);   //3.3.2
          function foo(i-1-1) {
          if (i-1-1 < 0){      //3.3.1
             return;
          }
          console.log('begin:' + i-1-1);   //3.3.2
          function foo(((i-1) - 1)-1){};   //3.3.3
          console.log('end:' + i-1-1); //3.3.4
          }
       console.log('end:' + i-1); //3.4
       }
    console.log('end:' + i); //4
}

FOO(3)

让我假装我是alwyas 3!

这就是:

  • 进入// 2和log 3
  • 进入//3.2和log 2
  • 进入//3.3.2和log 1
  • 进入//3.3.3并执行相同的操作并记录0
  • 进入虚构的//3.3.3.4并记录0因为//3.3.3的参数为0
  • 进入3.3.4并登录1
  • 进入3.4和log 2
  • 进入4和log 3