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
How you can see in this guide you have to
return
the recursive function:Explanation
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"
and"BBB"
, their lengths are not 0, go to else. Once in else,str3
is"AB"
, callmerge("AA", "BB")
."AA"
and"BB"
, their lengths are not 0, go to else. Once in else,str3
is now"ABAB"
, callmerge("A", "B")
."A"
and"B"
, their lengths are not 0, go to else. Once in else,str3
is now"ABABAB"
, callmerge("", "")
.str3
is logged, and returned.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.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.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.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: The recursive call is not returned on each call in the else branch, so the value of
str3
is returned to the callmerge("A", "B")
. The callmerge("A", "B")
does not return anything, it returnsundefined
. The same goes for all other calls - they have no return statement in the else branch soundefined
is returned. When all calls are resolved,undefined
is returned.Solution
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 ofstr3
up the call stack - the call returns"ABABAB"
, notundefined
.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 insteadstr3
. This is becausemerge("", "")
returned"ABABAB"
, which is the value ofstr3
. That result is then returned in callmerge("A", "B")
because of the new addedreturn
statement, which is then returned in callmerge("AA", "BB")
, and so on, until the call is completely resolved, and the returns the value ofstr3
.Here's the new code:
Before,
mergedString
would have received the valueundefined
. Since we now return the recursive calls, everything returned accordingly thus the value ofstr3
is returned, being stored into variablemergeString
.