简体   繁体   中英

Why would a return be undefined but console.log return an int?

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.

在你的else块中,它应该是return multiplyT(a, b, acc);

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));

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)); 

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);
    }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM