javascript - 为什么这个递归函数返回未定义?

标签 javascript recursion

我正在尝试编写一个使用递归组合两个字符串的函数。我的代码在下面,但我不知道为什么函数返回 undefined 尤其是当我在基本情况下 console.log 并且它不打印 undefined 而是打印正确的值时。

var str3=""
function merge(str1,str2){
    if(str1.length==0||str2.length==0){
        console.log(str3)
        return str3;
    }
    else{
        str3=str3+str1.substring(0,1)+str2.substring(0,1);
        merge(str1.substring(1,str1.length),str2.substring(1,str2.length))
    }
}

merge("AAA","BBB") //--> returns undefined but the console.log(str3) gives correct answer

最佳答案

解释

问题是你没有返回递归调用的结果,因此当整个调用 merge 时它是未定义的。已解决。

让我带你一步一步地执行:

  • 带参数 "AAA""BBB" ,他们的长度不为0,去别的。一旦进入,str3"AB" , 调用merge("AA", "BB") .
  • 带参数 "AA""BB" ,他们的长度不为0,去别的。一旦进入,str3现在是 "ABAB" , 调用merge("A", "B") .
  • 带参数 "A""B" ,他们的长度不为0,去别的。一旦进入,str3现在是 "ABABAB" , 调用merge("", "") .
  • 使用空字符串参数,长度为 0。现在转到 if 语句,其中 str3被记录并返回。
  • 由于merge("", "")调用已解决(返回到 "ABABAB"),我们从调用停止的地方继续 merge("A", "B") ,从而“向上”调用堆栈。
  • 我们从通话停止的地方开始 merge("A", "B") , 在 else 分支中。该调用中没有更多语句或表达式,因此已解决。 没有返回语句,所以默认返回 undefined .我们“向上”调用堆栈以调用 merge("AA", "BB")我们离开的地方。
  • 我们从通话停止的地方开始 merge("AA", "BB") , 在 else 分支中。该调用中没有更多语句或表达式,因此已解决。同样,没有返回语句,因此默认情况下它返回 undefined .我们“向上”调用堆栈以调用 merge("AAA", "BBB")我们离开的地方。
  • 我们从通话停止的地方开始 merge("AAA", "BBB") , 在 else 分支中。该调用中没有更多语句或表达式,因此已解决。同样,没有返回语句,因此默认情况下它返回 undefined .没有更多的电话,所以一切都解决了 - 和 merge("AAA", "BBB")返回 undefined .

  • TL;DR:在 else 分支中的每个调用都不会返回递归调用,因此 str3 的值返回调用 merge("A", "B") .来电merge("A", "B")不返回任何内容,它返回 undefined .所有其他调用也是如此——它们在 else 分支中没有返回语句,所以 undefined被退回。当所有调用都解决后,undefined被退回。

    解决方案

    解决方案是简单地添加 return到你的递归调用。这样,将返回每个调用的结果,“委托(delegate)”最终返回值 str3向上调用堆栈 - 调用返回 "ABABAB" ,而不是 undefined .

    由于我们现在返回调用的结果,上面的步骤 6、7 和 8 现在有一个退货声明 .这意味着我们不会返回 undefined , 而是 str3 .这是因为 merge("", "")返回 "ABABAB" ,即 str3 的值.然后在调用 merge("A", "B") 中返回该结果。因为新增了return语句,然后在调用 merge("AA", "BB") 中返回,以此类推,直到调用完全解决,并返回 str3 的值.

    这是新代码:

    var str3 = "";
    function merge(str1, str2) {
        if(str1.length == 0 || str2.length == 0) {
            console.log(str3);
            return str3;
        } else {
            str3 = str3 + str1.substring(0, 1) + str2.substring(0, 1);
            return merge(str1.substring(1, str1.length), str2.substring(1, str2.length)); //we return the recursive call
        }
    }
    
    var mergedString = merge("AAA","BBB"); //mergedString is "ABABAB"


    之前,mergedString会收到值 undefined .由于我们现在返回递归调用,因此所有内容都相应返回,因此 str3 的值返回,存储到变量 mergeString .

    关于javascript - 为什么这个递归函数返回未定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39321807/

    相关文章:

    javascript settimeout 在递归函数中不起作用

    javascript - 我怎样才能阻止链接将我发送到页面顶部

    javascript - 'this' 的值是多少?

    javascript - 如何检测滚动底部高度 < 30

    javascript - React Router with Private Route 呈现空白页面

    java - 递归名称搜索

    haskell - 自上而下的递归方案

    javascript - 陷入递归返回值

    javascript - 如何用坐标在图像上写文字?

    recursion - 你应该如何处理递归?