为什么代码仍然运行到递归函数的末尾?

时间:2019-04-18 23:47:00

标签: javascript recursion

我认为以下代码将永远不会到达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();

3 个答案:

答案 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之类的东西终止当前循环,切换或标签语句。