调试 javascript 中的递归

sid*_*hah 1 javascript recursion

function fact(n){
  if(n ==1){
    return 1
  } else{
    console.log(fact(n-1))
    return n*fact(n-1)
  }
}
Run Code Online (Sandbox Code Playgroud)

上面是代码片段。

这是调试递归阶乘代码的结果。 我不明白这些 1 是如何打印的,除了从 if 块返回的最后一个 1

这是调试递归阶乘代码的结果。我不明白这些 1 是如何打印的,除了从 if 块返回的最后一个 1 之外。

如果有人能解释这个程序的调试,那就太好了。

Nin*_*olz 5

如果您想查看递归函数正在做什么,我建议使用以下模式来获取递归调用顺序的有效视图。

  1. 添加一个级别变量,用于计算和维护深度。

  2. 使用两个输出,一个在函数的开头,一个在返回发生之前。

  3. 不要在进行输出的地方调用递归,因为这会调用递归,并且稍后返回时会再次调用递归。这会导致不必要的回避,并且看起来比应有的更复杂。获取一个变量来获取以下递归的结果并将其用于输出。


考虑到这一点,您得到的结果如下,第一列表示递归的级别或深度,第二列表示函数调用前半部分的值n,第二列表示返回值。

相同级别表示相同的函数,直到函数返回(有或没有显式值)才结束。

这里, level 上的函数0等待 level 函数的返回值1,而 level 函数2等待 level 的结果3,依此类推,直到函数返回一个值而不再调用该函数。基本上,递归以该值结束,并且所有未终止的函数都通过重新调整值来终止,在本例中为12624最终值120

level  pos  value                 type          comment
-----  ---  --------------------  ------------  ----------------------------
   0    in    5                   n             wait for result of level 1
   1    in        4               n             wait for level 2
   2    in            3           n             wait for level 3
   3    in                2       n             wait for level 4
   4    in                    1   n             deepest level
   4   out                    1   return value  terminate level 4
   3   out                2       return value  terminate level 3
   2   out            6           return value  terminate level 2
   1   out       24               return value  terminate level 1
   0   out  120                   return value  teminate return final result
Run Code Online (Sandbox Code Playgroud)

level  pos  value                 type          comment
-----  ---  --------------------  ------------  ----------------------------
   0    in    5                   n             wait for result of level 1
   1    in        4               n             wait for level 2
   2    in            3           n             wait for level 3
   3    in                2       n             wait for level 4
   4    in                    1   n             deepest level
   4   out                    1   return value  terminate level 4
   3   out                2       return value  terminate level 3
   2   out            6           return value  terminate level 2
   1   out       24               return value  terminate level 1
   0   out  120                   return value  teminate return final result
Run Code Online (Sandbox Code Playgroud)
function fact(n, level) {
    var returnValue;
    level = level || 0;
    console.log(level, 'in', n);
    if (n == 1) {
        console.log(level, 'out', 1);
        return 1;
    } else {
        returnValue = n * fact(n - 1, level + 1);
        console.log(level, 'out', returnValue);
        return returnValue;
    }
}

console.log(fact(5));
Run Code Online (Sandbox Code Playgroud)