这个递归函数如何工作?

时间:2012-06-19 06:44:33

标签: javascript recursion

我没看到这个递归函数是如何工作的:

function f(n) { g(n-1) }

function g(n) {
   alert("before: " + n);

   if(n > 0) f(n);

   alert("after: " + n);
}

f(2)​;​

我试图理解这段代码是有效的,我看到“1之前”,“0之前”和“0之后”执行但是......“1之后”是怎么来的?

我看到它正在执行...... f(2)调用g减去1,因此'n'变为1.警告(“之前:”+ n)执行,1大于0所以它将自己调用并且减去1.警报(“之前:”+ n)再次执行,0不大于0因此它将执行警报(“之后:”+ n)并且函数结束?...

编辑:感谢@FlorianMargaine和@Cyrille帮助我理解这背后的逻辑。 =)

4 个答案:

答案 0 :(得分:2)

after 1来自以下事实:在Javascript中,参数是按值而不是按引用传递的。因此,在第一次迭代中,调用调用if(n > 0) f(n);的{​​{1}}不会减少g(n-1)。它的值保留在n返回时,并保持其值为1。

这是一个调用图:

if(n > 0) f(n)

答案 1 :(得分:1)

查看来电顺序:

Calls f() with parameter 2
f() calls g() with parameter 2-1 -> 1
g() alerts "before: 1"
since n > 0, g() calls f() with parameter 1 -- and blocks further execution of current g() with parameter 1 - in other words, it goes down in "funception"
f() calls g() with parameter 1-1 -> 0
g() alerts "before: 0"
since n === 0, it skips the if
g() alerts "after: 0"
finally, the blocked execution can resume because the inner function has finished executing, so it alerts "after: 1"

它不是真正的“阻塞”,它只是在执行当前函数的其余部分之前执行内部函数。

要清楚地理解逻辑,只要尝试通过“说出来”来跟随它。

答案 2 :(得分:0)

现在更有意义吗? n≤0是基本情况。

function g(n) {
   alert("before: " + n);

   if(n > 0) g(n - 1);

   alert("after: " + n);
}

g(2)​;​

答案 3 :(得分:0)

每个函数调用最终返回。代码以递归方式调用f() / g(),但在某些时候n达到0并且f()语句中未调用if,因此它会警告{{} 1}}并开始返回调用链,最终到达第一个堆栈帧,after: 0n