我认为以下代码将永远不会到达console.log
行,因为next()
函数已经运行过,从而到达了console.log
行和if else
条件, return
也可以防止它,但事实并非如此。为什么?
var arr = ['a', 'b', 'c'];
var i = 0;
function next() {
if (i < arr.length) {
next(i++);
console.log('why go here 1:' + i); // 3,3,3
} else {
return;
}
console.log('why go here 2:' + i); // 3,3,3
}
next();
答案 0 :(得分:4)
一旦满足边缘条件(在这种情况下,一旦next()
大于i
,对arr.length
的所有调用将返回。这是递归的一部分,通常称为“展开”-每个递归调用都以其称为return的调用的形式返回。因此,一旦next()
函数返回,它将继续进行到console.log()
您可以调整代码,以便在函数启动时记录日志,并返回带有计数的值以可视化递归:
var arr = ['a', 'b', 'c'];
let i = 0;
let space = 1
function next() {
let s = space++
console.log(" ".repeat(s) + `next ${s} called`)
if (i < arr.length) {
next(i++);
} else {
console.log("edge condition -- finally start unwinding")
console.log(" ".repeat(s) + `next ${s} retured from edge condition`)
return;
}
console.log(" ".repeat(s) + `next ${s} retured`)
}
next();
在这里您可以看到四个next()
函数被调用而没有返回,但是一旦达到边缘条件,它们就会展开并以相反的顺序返回。
答案 1 :(得分:0)
您需要使用调试器或笔/纸逐步完成操作,以完全了解流程。
当next(i++)
返回时,就像在任何函数调用之后一样,它将转到下一行。如果要停止代码,则必须在调用return
之后next(i++)
。例如:return next(i++);
或next(i++); return;
答案 2 :(得分:0)
if
语句/函数将运行范围内的所有内容,除非有诸如break
之类的东西终止当前循环,切换或标签语句。