这个递归函数如何解决?为什么它会输出它的作用

时间:2016-10-30 22:15:43

标签: javascript function recursion

我发现自己无法理解这个递归函数的例子:

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

输出结果为:

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

我理解普通函数和嵌套函数是如何工作的,我认为return;i低于0时应该退出函数,所以当i = -1时,第一个console.log()没有显示,但为什么在foo(-1 - 1)之后我们得到输出end:0

2 个答案:

答案 0 :(得分:6)

要了解您必须可视化堆栈。让我带您完成执行过程:

  1. 我们首先调用foo(3),因此i为3.由于i不小于0,请记录begin:3。致电foo(2)
  2. i现在是2.由于i不小于0,请记录begin:2。致电foo(1)
  3. i现在为1.由于i不小于0,请记录begin:1。致电foo(0)
  4. i现在为0.由于i不小于0,请记录begin:0。致电foo(-1)
  5. i现在为-1。由于i 小于0,我们返回并向上移动堆栈。从我们中断的地方继续,第二次登录foo(0)

    console.log('end:' + i);
    

    end:0已被记录,因为i等于0. foo(0)已解决,上堆到foo(1)

  6. foo(1)的第二个登录继续。记录end:1是因为i等于1. foo(1)已解决,请将堆栈上移至foo(2)
  7. foo(2)的第二个登录继续。系统会记录end:2,因为i等于2. foo(2)已解决,请将堆栈上移至foo(3)
  8. foo(3)的第二个登录继续。系统会记录end:3,因为i等于3. foo(3)已解决,因此呼叫已完全解决。
  9. 这将产生:

    begin:3 //Step 1
    begin:2 //Step 2
    begin:1 //Step 3
    begin:0 //Step 4
    end:0   //Step 5
    end:1   //Step 6
    end:2   //Step 7
    end:3   //Step 8
    

    现在,回答这个问题:

      

    但是为什么在foo(-1 - 1)之后我们得到输出结束:0?

    我们从不致电foo(-1 - 1),因为foo(-1)会立即返回 - 这是基本情况。它开始记录end:i i在哪里升序的原因是因为在你递归并调用foo(i - 1)之前,执行会继续执行。因此,它会记录end:i,然后解析调用。

答案 1 :(得分:2)

实际上,当i = 0时函数会停止,但是因为foo(i-1)在console.log之前被调用('end:'+ i);所有console.log的输出('begin:'+ i);在显示结束之前显示i值。

事实上,这里真正发生的是:

  • FOO(3)
    • i = 3 - &gt;显示:“开始3”;
    • 致电foo(2)
      • i = 2 - &gt;显示:“开始2”;
      • 致电foo(1)
        • i = 1 - &gt;显示:“开始1”;
        • 拨打foo(0)
          • i = 0 - &gt;显示:“开始0”;
          • 调用foo(-1) - &gt;返回
          • 返回foo(0),显示“end 0”
          • foo结束(0)
        • 返回foo(1),显示“end 1”
        • foo结束(1)...

等等。