为什么 return 是未定义的,而 console.log return 是一个整数?

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

所以我有以下功能:

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

}

它被调用:

console.log(multiplyT(5,3,0));

并给出这个:

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

作为输出。我感到困惑的是,为什么 acc 会根据返回的内容为 console.log 给出正确的值,但会给出 "undefined"。

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

您还需要从 else 块return。

在您的情况下,即使 acc 的值已更新,但当 b != 0

时,该值未被 return 编辑

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

您正在递归调用 multiplyT 函数,但您并未控制 return。然后,multiplyT(5,3,0) 在第一次调用中没有 return 值,然后函数 return 未定义。

确实栈在执行,但是第一个调用更重要:它需要从return最终值的递归内部函数中获取值。

修复 else 分支中的代码,以便您可以 return 递归调用:

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 都是一个值,对于那些没有的迭代,你会得到未定义的——就像你将变量设置为任何没有 return 的函数一样价值。

虽然它与递归混淆,因为您在这种情况下看到的 return 值来自第一次调用和最后完成的迭代。与 return 中断方法执行的常规方法调用不同——将它从它来的地方发送回,递归仍然通过调用堆栈返回,returning 任何它必须返回的值以调用它们的相反顺序返回,包括未定义的。因此,它实际上为您的 console.log 调用提供了四个 return 值:15、undefined、undefined、undefined。

因为它是同步的,所以 console.log 在它调用的方法完成之前无法执行。它输出的是它得到的最后一个值,或者是未定义的。如果您在 else 块中的方法调用之后坚持 return,您会看到您得到 5,或者函数第一次迭代后 acc 的值。

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

我在处理我的一个项目时想出了一个很好的解决方案,在这个项目中我遍历了一个复杂的 JSON 对象 return 一些关于搜索 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;
       }
   }
}

在这里,我们 运行 一个 while 循环来查看递归函数调用 return 是真值还是未定义。如果 return 不是 undefined,它将 return 数据。