Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.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 理解递归背后的执行-递归如何确定何时停止?_Javascript_Recursion_Theory - Fatal编程技术网

Javascript 理解递归背后的执行-递归如何确定何时停止?

Javascript 理解递归背后的执行-递归如何确定何时停止?,javascript,recursion,theory,Javascript,Recursion,Theory,我知道这里有很多递归线程。从技术上讲,我确实理解递归背后的原理,我只是更好奇实际的递归计数器存储在哪里,或者编译器如何跟踪它 代码可能更好地理解这一点。我用javascript创建了一个简单的递归函数 function factorial(number){ if (number > 1) { return number * factorial(number - 1); } else { return number; } } 现在,每个人都明白这是怎么回事了

我知道这里有很多递归线程。从技术上讲,我确实理解递归背后的原理,我只是更好奇实际的递归计数器存储在哪里,或者编译器如何跟踪它

代码可能更好地理解这一点。我用javascript创建了一个简单的递归函数

function factorial(number){
    if (number > 1) {
    return number * factorial(number - 1);
  } else {
    return number;
  }
}
现在,每个人都明白这是怎么回事了。我们调用阶乘上的递归函数,该函数递归地重复,直到函数结束

我的问题是,阶乘函数为什么会在正确的时间停止执行递归?如果我们试着在头脑中调试函数,我的理解是,它看起来像这样:

我们称之为〈代码〉阶乘(3)

  • 调用函数->加载参数
  • 计算IF条件->3>1->应用递归函数
  • 3*递归(2)*递归(1)=>3*2*1=6
  • 现在我的问题是,这怎么可能?为什么a)如果我们将递归计数器减少到1,我们没有输入
    否则{
    语句,因为它的计算结果应该为false,以及b)递归计数器为什么知道只循环递归函数n次

    为了更好地说明,我添加了以下代码行
    document.write(“使用数字“+number+”
    ”)输入;
    因此每次输入if条件时,我们都会将其打印出来

    函数阶乘(数){
    如果(数字>1){
    文件。写入(“以数字“+数字+”输入”
    ”; 返回数*阶乘(数-1); }否则{ 返回号码; } }
    document.write(阶乘(3)+“
    ”);
    这里有一个递归正在做的口头描述,太详细了:

  • 文档中调用
    factorial(3)
    。write()

  • factorial(3)
    想要返回
    3*factorial(2)
    。在返回值之前,它必须先计算出
    factorial(2)
    的含义

  • 所以现在我们有了
    factorial(3)
    等待
    factorial(2)
    的结果运行,并希望返回
    2*factorial(1)
    。在返回值之前,它必须计算出
    factorial(1)
    的含义

  • 现在我们有
    factorial(3)
    正在等待
    factorial(2)
    的结果,它正在等待
    factorial(1)
    的结果,并且看到它的输入是1,所以点击“else”块,只需将1返回给它的调用者
    factorial(2)

  • 现在,
    factorial(2)
    有了它所需要的,因此可以将
    2*1
    返回给它的调用者,
    factorial(3)

  • 现在,
    factorial(3)
    有了它所需要的,因此可以将
    3*2
    返回给它的调用者

  • 调用的
    document.write
    收到“6”

  • 递归“知道”在哪里停止,因为它最终只返回数字1,而不是返回依赖于对
    factorial()的另一个调用的内容
    。如果函数总是试图调用自己,那么就没有办法退出递归循环;它会一直运行,直到堆栈溢出

    除了
    factorial(1)
    ,每次调用
    factorial(n)
    都会调用
    factorial(n-1)
    ——因此请注意
    factorial(0)
    factorial(-1)
    factorial(1.01)
    将永远不会到达1,因此递归将一直运行,直到堆栈溢出。编写递归函数时,最好注意并处理永远不会到达出口点的输入;在这种情况下,如果输入不是正整数,您可能希望抛出错误

    如果我们调用阶乘(2-1)上的递归操作,为什么计数器没有循环到更低的值,为什么我们从来没有返回到初始的else{return number;}

    确实如此,但是您的
    文档。函数中的write
    位于
    if
    块中,因此当函数进入
    else
    块时,没有打印任何内容。下面是同一函数的更详细版本,这可能会让您更清楚地了解发生了什么:

    函数阶乘(数){
    文件。写入(“以数字“+数字+”
    )输入); 如果(数字>1){ document.write(“递归
    ”) 返回数*阶乘(数-1); }否则{ document.write(“返回1
    ”) 返回号码; } }
    document.write(阶乘(3)+“
    ”);
    这里是递归的口头描述,太详细了:

  • 文档中调用
    factorial(3)
    。write()

  • factorial(3)
    想要返回
    3*factorial(2)
    。在返回值之前,它必须先计算出
    factorial(2)
    的含义

  • 所以现在我们有了
    factorial(3)
    等待
    factorial(2)
    的结果运行,并希望返回
    2*factorial(1)
    。在返回值之前,它必须计算出
    factorial(1)
    的含义

  • 现在我们有
    factorial(3)
    正在等待
    factorial(2)
    的结果,它正在等待
    factorial(1)
    的结果,并且看到它的输入是1,所以点击“else”块,只需将1返回给它的调用者
    factorial(2)

  • 现在,
    factorial(2)
    有了它所需要的,因此可以将
    2*1
    返回给它的调用者,
    factorial(3)

  • 现在,
    factorial(3)
    有了它所需要的,因此可以返回
    3*2
    t