JavaScript中递归和执行流程的更清晰的解释?

时间:2009-04-06 03:11:05

标签: javascript recursion

我正在阅读Eloquent JavaScript,我遇到了这个难题的例子:

  

考虑这个难题:从开始   数字1和反复   加5或乘以3,an   无限量的新数字都可以   产生的。你会怎么写的?   在给定数字的情况下尝试的功能   找到一系列的补充和   产生它的乘法   号码?

以下是解决方案的代码:

function findSequence(goal) {
  function find(start, history) {
    if (start == goal)
      return history;
    else if (start > goal)
      return null;
    else
      return find(start + 5, "(" + history + " + 5)") ||
             find(start * 3, "(" + history + " * 3)");
  }
  return find(1, "1");
}

print(findSequence(24));

如果没有参数start和goal的值,有人可以清楚dod find如何执行吗?递归是怎么发生的?

3 个答案:

答案 0 :(得分:5)

但是find 没有<{1}}和start的值而执行。它首先使用goal的值1执行,而start的唯一值是goal

也许你对操作的顺序感到困惑。我们在那里看到函数{em}的声明24。在声明期间,不执行任何代码。 findSequence函数仅在最后一行执行,执行函数的结果将被打印出来。

findSequence的声明中,有另一个函数findSequence的声明。再一次,直到后来它才会被执行。 find函数只有一个可执行代码行,即调用findSequence的代码。执行该一行会递归地触发find(1, "1")执行若干次。 find函数引用find;当Javascript解释器执行代码时,goal始终引用goal的参数,因为在此示例中findSequence仅被调用一次,findSequence始终具有相同的值,goal

您应该能够看到递归发生的位置。如果24等于start,则函数停止;它返回它到达该数字的历史。如果goal大于start,则返回goal,表示该路径不是目标号码的路径。如果null仍小于start,则函数会尝试调用自身,其起始值加上5.如果返回非空值,那么返回的是。否则,它会尝试乘以3并返回该历史值。

请注意,虽然此代码可以返回许多数字,但它无法返回所有数字。例如,如果目标为goal2将返回findSequence,因为无法从null开始并通过添加{12 1}}或乘以5

答案 1 :(得分:1)

当在findSequence内部调用find时,它可以访问在findSequence的定义中设置的目标变量。一个简单的例子是:

function outerFunction() {
  var a = 2;
  function innerFunction() {
    alert(a);
  }
  innerFunction();
}
outerFunction();

起始变量是在以下情况下定义的:

return find(1, "1");

有效地将初始开始变量设为1,目标变量为24,并且在第一次过程中具有“1”的历史记录。

编辑:根据Rob的评论,闭包实际上并不是造成这种情况的原因,因为find()没有在findSequence()之外执行,范围确定导致找到目标。

答案 2 :(得分:0)

如果我正确理解你的问题:最后一行代码是调用findSequence(),目标是24.在findSequence()中有一个名为find()的函数,它被定义然后在返回时调用findSequence的语句,start等于1,历史等于1。