JS、递归、函数栈例子,难懂

JS, Recursion, Function Stack Example, Hard to Understand

下面是来自 MDN Function scope 的示例。我不明白 end: 0end: 的其余部分是如何打印的。我原以为 console.log("end: " + i); 永远不会达到。

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

如果我写:

console.log("begin");
my_custom_function(1);
console.log("end")

然后 console.log 将开始记录,然后 my_custom_function 将被调用,当 my_custom_function 完成后它将从它停止的地方开始并且 console.log 将记录结束。

一模一样

foo 完成后,它将 return 到调用函数(恰好也是 foo)并从中断处继续。

所有递归的诀窍是退出条件。没有它,该函数将永远 运行 或系统 运行 内存不足。 foo 的退出条件是 if (i < 0) return;。 现在因为 javascript 至少在这种情况下是 运行 同步的,所以它会在继续下一行代码之前完成它正在做的任何事情。

该函数使用 foo(i - 1); 调用自身,后者将依次调用自身,依此类推,直到满足退出条件。因此,将退出条件置于递归调用之前至关重要。

为了更容易理解,请考虑每个连续调用的 i 的值:

foo(3)
  foo(2)
    foo(1)
      foo(0) // exit condition is met, ending the recursion
      print end 0
    print end 1
  print end 2
print end 3

分块考虑。下面我添加了显示实际 i 值并在每次递归时缩进的每个步骤。可以看到递归完成后,就会完成对前面每一个块的函数调用。

foo(3) {
    if (3 < 0) return;
    console.log("begin: " + 3);
    foo(3-1) {
        if (2 < 0) return;
        console.log("begin: " + 2);
        foo(2-1) {
            if (1 < 0) return;
            console.log("begin: " + 1);
            foo(1-1) {
                if (0 < 0) return;
                console.log("begin: " + 0);
                foo(0-1){
                    if (-1 < 0) return; // Exit recursion
                }
                console.log("end: " + 0);
            }
            console.log("end: " + 1);
        }
        console.log("end: " + 2);
    }
    console.log("end: " + 3);
}

function foo() {
  if (i < 0) {
console.log("end: " + i);
clearInterval(lauch);//close the interval
} else { // with an else
  console.log("begin: " + i);
 i -= 1;
}
  
}

var i = 3;//global var
var lauch;
start();

function start () {
 lauch = setInterval(foo, 1000); // 1 sec or 1000 millisecondes, the function reaload
}

也许这是您要找的?