问题
So I have the following function:
var multiplyT = function(a, b, acc) {
if (b == 0) {
console.log("BASE CASE: ", acc);
return acc;
} else {
b--;
acc = acc + a;
console.log("NOT THE BASE CASE: ", a,b,acc);
multiplyT(a, b, acc);
}
}
It gets called with:
console.log(multiplyT(5,3,0));
And gives this:
NOT THE BASE CASE: 5 2 5
NOT THE BASE CASE: 5 1 10
NOT THE BASE CASE: 5 0 15
BASE CASE: 15
undefined
As output. What I am confused about is why acc would give the correct value for the console.log but be "undefined" according to what is returned.
回答1:
This is a good one. Recursion can make your head spin. The reason it's undefined is because not all iterations return a value, and for those that don't you get undefined -- the same as if you set a variable to any function that doesn't return a value.
It gets confusing with recursion though, because the return value you're seeing in this case is from the first-called and last-completed iteration. Unlike a regular method call where return breaks execution of the method -- sending it back to from wherever it came, recursion still has wind its way back through the call stack, returning whatever values it has to give back, including undefined, in the reverse order in which they were called. So it's actually giving your console.log call four return values: 15, undefined, undefined, undefined.
Because it synchronous, console.log can't execute until the method it called is done. What it outputs is the last value it gets, or undefined. If you stick in a return after the method call in your else block, you'll see you get 5, or the value of acc after the first iteration of the function.
var multiplyT = function(a, b, acc) {
if (b == 0) {
console.log("BASE CASE: ", acc);
return acc;
} else {
b--;
acc = acc + a;
console.log("NOT THE BASE CASE: ", a,b,acc);
multiplyT(a, b, acc);
return acc;
}
}
console.log(multiplyT(5,3,0));
回答2:
In your else block, it should be return multiplyT(a, b, acc);
回答3:
You need to return from the else block as well.
In your case even though the value of acc
is updated that value is mot returned when b != 0
var multiplyT = function(a, b, acc) {
if (b == 0) {
console.log("BASE CASE: ", acc);
return acc;
} else {
b--;
acc = acc + a;
console.log("NOT THE BASE CASE: ", a, b, acc);
return multiplyT(a, b, acc); //return here
}
}
console.log(multiplyT(5, 3, 0));
回答4:
You're calling recursively the multiplyT function, but you're not controlling the return. Then, multiplyT(5,3,0) does not return a value in the first call and the function then returns undefined.
It's true that the stack is executing, but the first call is the more important: it needs to get the value from the recursive inner function that returned the final value.
Fix the code in the else branch so you can return the recursive call:
var multiplyT = function(a, b, acc) {
if (b == 0) {
console.log("BASE CASE: ", acc);
return acc;
} else {
b--;
acc = acc + a;
console.log("NOT THE BASE CASE: ", a,b,acc);
return multiplyT(a, b, acc);
}
}
回答5:
I've come up with a good solution to this while working on one of my projects in which I traverse a complex JSON object to return some data on searching for the id.
var multiplyT = function(a, b, acc) {
if(b == 0) {
console.log("BASE CASE : ", acc);
return acc;
} else {
var ret;
b--; acc += a;
console.log("NOT THE BASE CASE: ",a,b,acc);
while( ret = multiplyT(a,b,acc) ) {
return ret;
}
}
}
Here, we run a while loop to see if the recursed function call returns a true value or undefined. If returns something other than undefined
, it will return the data.
来源:https://stackoverflow.com/questions/30386685/why-would-a-return-be-undefined-but-console-log-return-an-int