You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript递归案例foo(3)执行逻辑与运行结果疑问解答

JavaScript递归代码运行逻辑解答

首先给出完整代码:

let ar = [];

function foo(i) {
  if (i < 0)
    return console.log("test");

  ar.push(i);
  console.log(i, Boolean(i<0));
  foo(i - 1);
  ar.push(i);
  console.log(i, Boolean(i<0));
}

foo(3)
console.log('ar=', JSON.stringify( ar ))

运行后的控制台输出如下:

3 false
2 false
1 false
0 false
test
0 false
1 false
2 false
3 false
ar= [3,2,1,0,0,1,2,3

调用foo(3)时表达式0 < 0的求值逻辑

当递归调用到foo(0)时,if判断条件i < 0即0 < 0会被执行:JavaScript中数字0属于number类型,0和0做小于比较,运算结果为布尔值false,因此if分支的return逻辑被跳过,函数继续执行后续的ar.push(0)、console.log等代码。

return语句后直接返回console.log("test")是否属于特殊用法

不属于特殊用法,是JavaScript常规的表达式求值逻辑:

  • console.log("test")执行后会输出对应内容,本身的返回值固定为undefined
  • 该写法等价于先执行console.log("test"),再将其返回值undefined作为foo函数的返回值返回,拆分成两行写效果完全一致:
    console.log("test");
    return;
    

ar数组索引3和4位置的两个0是否是0值被求值两次

不是,两个0是同一个foo(0)函数执行上下文的ar.push(i)分别在递推、回溯阶段各执行一次导致的:

  • 第一个0(索引3)是递推阶段生成:刚进入foo(0)时第一次执行ar.push(0),此时ar为[3,2,1,0]
  • 第二个0(索引4)是回溯阶段生成:foo(-1)执行完毕返回后,回到foo(0)中递归调用foo(i-1)后的代码继续执行,第二次执行ar.push(0),此时ar为[3,2,1,0,0]

1-1计算时是否会触发foo(0)调用

是的,foo(1)执行到递归调用语句foo(i - 1)时,i的值为1,i-1计算结果为0,会直接触发foo(0)调用。

递归调用位于两次push和log之间对执行顺序的影响

这个代码顺序直接决定了两段操作分别在递归的不同阶段执行:

  • 递归调用前的ar.push(i)和console.log属于递推阶段执行:调用链从外层到内层逐层执行,i按3→2→1→0的顺序执行,对应第一次打印顺序为3、2、1、0
  • 递归调用后的ar.push(i)和console.log属于回溯阶段执行:调用链从内层返回外层时逐层执行,i按0→1→2→3的顺序执行,对应第二次打印顺序为0、1、2、3

最终ar数组的内容也由这个顺序决定,呈现先递推入栈3、2、1、0,再回溯入栈0、1、2、3的规律,得到最终的数组结果。


内容的提问来源于stack exchange,提问作者Jay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:45:03