为什么这个递归的JavaScript函数返回undefined?

3
在以下的递归函数中,我期望函数在结束时返回"arrived",但实际上它返回undefined。难道不是代码执行到if块时应该返回吗?欢迎您对此发表评论。
function myFun(i){
    if(i===0){return ('arrived');}
    i = i - 1;
    myFun(i);
}

如果我将代码更改如下,则会返回"arrived",但仍不知道为什么上面的代码不返回"arrived"
function myFun(i){
    if(i===0){return ('arrived');}
    i = i - 1;
    return myFun(i);
}

@安东尼,i被发送到参数中。 - camel-man
如果你有一个函数 foo,它仅仅调用一个返回值为 "BAR" 的函数 bar,那么如果 foo 没有 return 语句,你是否期望 foo 返回 bar 函数的调用结果呢?递归函数也是一样的。function foo() { bar() } function bar() { return "bar" } foo(); - user2437417
1
你的例子完全有道理。谢谢! - AdamO
2个回答

7
第一个函数没有返回值,因为所有代码路径必须返回一个值。在第一行之后,没有return语句。只有当使用0作为参数调用时才会返回一个值。

如果您调用函数myFun(5),那么它最终会到达myFun(0),此时应该返回"arrived",对吧?所以,我的意思是,如果我调用myFun(5),那么它与我直接使用参数0调用函数的myFun(0)有什么不同呢? - AdamO
在这种情况下,您有6个嵌套(递归)调用。第6次调用使用i === 0完成,并且是的,它将字符串返回给第五次调用的上下文。该值然后被“抛弃”,因为从第5(第4和第3等)次调用发生的位置,即第3行,没有return语句。 - Peter B
现在我明白了,解释得很好,谢谢。 - AdamO

1

递归是一种函数式编程的遗产,所以采用函数式编程风格编写程序将产生最佳结果。

这意味着避免使用以下内容:

  • 不返回值的命令式语句(如forifswitch等)
  • 变量改变或重新赋值(如i=i+1

const myFun = i =>
  i === 0
    ? "arrived"
    : myFun (i - 1)
    
console.log (myFun (10))
// "arrived"

注意表达式与语句不同,会产生一个值。我们进行了以下更改:
  • function 语句 function myFun (i) { ... } 被替换为函数 表达式 myFun (i) => ...
  • if 语句被替换为三元 表达式,例如 condition ? ifTrue : ifFalse
  • 变量赋值语句 i = i - 1; myFun(i) 被替换为 表达式 myFun(i - 1)

请注意,return 语句本身是一种副作用,对于功能性 JavaScript 程序几乎没有用处。

跟随这里的其他答案,所有代码路径必须返回一个值!以函数式风格编写程序的优点在于,您无法编写不返回值的函数,也不能编写只有一个分支的条件。

TL;DR:使用函数式风格,您的问题将自动消失


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接