我没看到这个递归函数是如何工作的:
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帮助我理解这背后的逻辑。 =)
答案 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: 0
为n
。