Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么返回是未定义的,而console.log返回int?_Javascript_Recursion_Console.log - Fatal编程技术网

Javascript 为什么返回是未定义的,而console.log返回int?

Javascript 为什么返回是未定义的,而console.log返回int?,javascript,recursion,console.log,Javascript,Recursion,Console.log,所以我有以下功能: 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

所以我有以下功能:

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提供正确的值,但根据返回的内容是“未定义的”。

在else块中,它应该是
返回倍数(a、b、acc)

您还需要从else块返回

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

var multiplyT=函数(a、b、acc){
如果(b==0){
控制台日志(“基本情况:”,acc);
返回acc;
}否则{
b--;
acc=acc+a;
log(“不是基本情况:”,a,b,acc);
返回倍数(a、b、acc);//在此处返回
}
}

log(倍数(5,3,0))递归调用multiplyT函数,但不控制返回。然后,multiplyT(5,3,0)在第一次调用中不返回值,然后该函数返回undefined

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

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

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

这是一个好的。递归会让你头晕目眩。它未定义的原因是,并非所有迭代都返回值,对于那些未返回值的迭代,您将得到未定义的值——这与将变量设置为任何不返回值的函数一样

不过,它会与递归混淆,因为您在本例中看到的返回值来自第一次调用和最后一次完成的迭代。与常规方法调用不同的是,返回中断了方法的执行——将方法从任何地方发送回,递归仍然在调用堆栈中迂回,以调用的相反顺序返回它必须返回的任何值,包括未定义的值。所以它实际上给了你的console.log调用四个返回值:15,undefined,undefined,undefined

因为它是同步的,所以在它调用的方法完成之前,console.log无法执行。它输出的是它最后得到的值,或者是未定义的值。如果您在else块中的方法调用后坚持返回,您将看到在函数的第一次迭代后得到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对象,以返回搜索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循环来查看递归函数调用是否返回真值或未定义值。如果返回的不是未定义的
,它将返回数据