为什么这个递归函数返回 undefined? [英] Why does this recursive function return 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:
- 使用参数
"AAA"
和"BBB"
,它们的长度不为 0,转到 else.进入else后,str3
就是"AB"
,调用merge("AA", "BB")
. - 使用参数
"AA"
和"BB"
,它们的长度不为0,转到else.一旦进入else,str3
现在是"ABAB"
,调用merge("A", "B")
. - 带参数
"A"
和"B"
,它们的长度不为0,转到else.一旦进入else,str3
现在是"ABABAB"
,调用merge("", "")
. - 用空字符串参数,长度为 0.现在转到 if 语句,记录
str3
并返回. - 由于
merge("", "")
调用已解析(返回到"ABABAB"
),我们从调用中中断的地方继续merge("A", "B")
,从而向上"调用堆栈. - 我们从在 else 分支中调用
merge("A", "B")
的地方开始.该调用中不再有语句或表达式,因此已解决.没有返回语句,所以默认返回undefined
.我们向上"调用调用堆栈以调用merge("AA", "BB")
我们离开的地方. - 我们从我们中断的地方开始调用
合并(AA",BB")
,在 else 分支中.该调用中不再有语句或表达式,因此已解决.同样,没有 return 语句,因此默认情况下它返回undefined
.我们向上"调用堆栈调用merge("AAA", "BBB")
我们离开的地方. - 我们从我们离开的地方开始调用
merge("AAA", "BBB")
, 在 else 分支中.该调用中不再有语句或表达式,因此已解决.同样,没有 return 语句,因此默认情况下它返回undefined
.没有更多的调用,所以一切都解决了 -merge("AAA", "BBB")
返回undefined
.
- With arguments
"AAA"
and"BBB"
, their lengths are not 0, go to else. Once in else,str3
is"AB"
, callmerge("AA", "BB")
. - With arguments
"AA"
and"BB"
, their lengths are not 0, go to else. Once in else,str3
is now"ABAB"
, callmerge("A", "B")
. - With arguments
"A"
and"B"
, their lengths are not 0, go to else. Once in else,str3
is now"ABABAB"
, callmerge("", "")
. - With empty string arguments, length is 0. Now go to the if statement, where
str3
is logged, and returned. - Since the
merge("", "")
call has resolved (to"ABABAB"
as it is returned), we continue where we left off in the callmerge("A", "B")
, thus going "up" the call stack. - 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 returnsundefined
. We go "up" the call stack to callmerge("AA", "BB")
where we left off. - 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 returnsundefined
. We go "up" the call stack to callmerge("AAA", "BBB")
where we left off. - 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 returnsundefined
. There are no more calls, so everything's resolved - andmerge("AAA", "BBB")
returnsundefined
.
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屋!