为什么这个递归函数返回 undefined? [英] Why does this recursive function return undefined?

查看:47
本文介绍了为什么这个递归函数返回 undefined?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm attempting to write a function that combines two strings using recursion. My code is below but I don't know why the function returns undefined especially when I console.log within the base case and it does not print undefined but instead the correct value.

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 的整个调用被解析时它是未定义的.

The problem is that you don't return the recursive call's result, thus it is undefined when the whole call to merge is resolved.

让我逐步带您完成执行过程:

Let me take you through the execution, step-by-step:

  1. 使用参数 "AAA""BBB",它们的长度不为 0,转到 else.进入else后,str3就是"AB",调用merge("AA", "BB").
  2. 使用参数"AA""BB",它们的长度不为0,转到else.一旦进入else,str3现在是"ABAB",调用merge("A", "B").
  3. 带参数"A""B",它们的长度不为0,转到else.一旦进入else,str3现在是"ABABAB",调用merge("", "").
  4. 用空字符串参数,长度为 0.现在转到 if 语句,记录 str3 并返回.
  5. 由于 merge("", "") 调用已解析(返回到 "ABABAB"),我们从调用中中断的地方继续 merge("A", "B"),从而向上"调用堆栈.
  6. 我们从在 else 分支中调用 merge("A", "B") 的地方开始.该调用中不再有语句或表达式,因此已解决.没有返回语句,所以默认返回undefined.我们向上"调用调用堆栈以调用 merge("AA", "BB") 我们离开的地方.
  7. 我们从我们中断的地方开始调用 合并(AA",BB"),在 else 分支中.该调用中不再有语句或表达式,因此已解决.同样,没有 return 语句,因此默认情况下它返回 undefined.我们向上"调用堆栈调用 merge("AAA", "BBB") 我们离开的地方.
  8. 我们从我们离开的地方开始调用 merge("AAA", "BBB"), 在 else 分支中.该调用中不再有语句或表达式,因此已解决.同样,没有 return 语句,因此默认情况下它返回 undefined.没有更多的调用,所以一切都解决了 - merge("AAA", "BBB") 返回 undefined.
  1. With arguments "AAA" and "BBB", their lengths are not 0, go to else. Once in else, str3 is "AB", call merge("AA", "BB").
  2. With arguments "AA" and "BB", their lengths are not 0, go to else. Once in else, str3 is now "ABAB", call merge("A", "B").
  3. With arguments "A" and "B", their lengths are not 0, go to else. Once in else, str3 is now "ABABAB", call merge("", "").
  4. With empty string arguments, length is 0. Now go to the if statement, where str3 is logged, and returned.
  5. Since the merge("", "") call has resolved (to "ABABAB" as it is returned), we continue where we left off in the call merge("A", "B"), thus going "up" the call stack.
  6. We start where we left off in call merge("A", "B"), in the else branch. There are no more statements or expressions in that call, so it's resolved. There are no return statements, so by default it returns undefined. We go "up" the call stack to call merge("AA", "BB") where we left off.
  7. We start where we left off in call merge("AA", "BB"), in the else branch. There are no more statements or expressions in that call, so it's resolved. Again, there are no return statements so by default it returns undefined. We go "up" the call stack to call merge("AAA", "BBB") where we left off.
  8. We start where we left off in call merge("AAA", "BBB"), in the else branch. There are no more statements or expressions in that call, so it's resolved. Again, there are no return statements so by default it returns undefined. There are no more calls, so everything's resolved - and merge("AAA", "BBB") returns undefined.

TL;DR:在else分支中的每次调用都不会返回递归调用,因此将str3的值返回给调用merge("A", "B").调用 merge("A", "B") 不返回任何内容,它返回 undefined.所有其他调用也是如此——它们在 else 分支中没有 return 语句,所以 undefined 被返回.当所有调用都被解析时,返回undefined.

TL;DR: The recursive call is not returned on each call in the else branch, so the value of str3 is returned to the call merge("A", "B"). The call merge("A", "B") does not return anything, it returns undefined. The same goes for all other calls - they have no return statement in the else branch so undefined is returned. When all calls are resolved, undefined is returned.

解决方案

解决方案是简单地将 return 添加到您的递归调用中.这样,每次调用的结果都会被返回,将 str3 的最终返回值委托"到调用堆栈中 - 调用返回 "ABABAB",而不是 未定义.

The solution is to simply prepend return to your recursive calls. That way, the result of each call would be returned, 'delegating' the final returned value of str3 up the call stack - the call returns "ABABAB", not undefined.

既然我们现在返回调用的结果,上面的第 6、7 和 8 步现在有一个返回语句.这意味着我们不返回 undefined,而是返回 str3.这是因为merge("", "")返回了"ABABAB",也就是str3的值.由于新添加的 return 语句,该结果然后在 call merge("A", "B") 中返回,然后在 call merge("AA", "BB"),依此类推,直到调用完全解析,返回str3的值.

Since we now return the result of the call, steps 6, 7, and 8 above now have a return statement. That means we don't return undefined, but instead str3. This is because merge("", "") returned "ABABAB", which is the value of str3. That result is then returned in call merge("A", "B") because of the new added return statement, which is then returned in call merge("AA", "BB"), and so on, until the call is completely resolved, and the returns the value of 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 中.

Before, mergedString would have received the value undefined. Since we now return the recursive calls, everything returned accordingly thus the value of str3 is returned, being stored into variable mergeString.

这篇关于为什么这个递归函数返回 undefined?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆