我发现自己无法理解这个递归函数的例子:
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
?
答案 0 :(得分:6)
要了解您必须可视化堆栈。让我带您完成执行过程:
foo(3)
,因此i
为3.由于i
不小于0,请记录begin:3
。致电foo(2)
i
现在是2.由于i
不小于0,请记录begin:2
。致电foo(1)
i
现在为1.由于i
不小于0,请记录begin:1
。致电foo(0)
i
现在为0.由于i
不小于0,请记录begin:0
。致电foo(-1)
i
现在为-1。由于i
小于0,我们返回并向上移动堆栈。从我们中断的地方继续,第二次登录foo(0)
:
console.log('end:' + i);
end:0
已被记录,因为i
等于0. foo(0)
已解决,上堆到foo(1)
foo(1)
的第二个登录继续。记录end:1
是因为i
等于1. foo(1)
已解决,请将堆栈上移至foo(2)
foo(2)
的第二个登录继续。系统会记录end:2
,因为i
等于2. foo(2)
已解决,请将堆栈上移至foo(3)
。foo(3)
的第二个登录继续。系统会记录end:3
,因为i
等于3. foo(3)
已解决,因此呼叫已完全解决。这将产生:
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值。
事实上,这里真正发生的是:
等等。