【问题标题】:Can some explain how return statements work with recursion in javascript?有人能解释一下 return 语句如何与 javascript 中的递归一起工作吗?
【发布时间】:2017-01-22 00:00:37
【问题描述】:

我已经查看了论坛,我看到了一些标题相似但没有回答我问题的论坛。我注意到如果我创建一个递归函数,return 语句会在它看起来像的终止语句之后返回。有人可以向我解释这是如何工作的吗?谢谢

function recur(n=10){
  if(n===0){
    return "";
  }
  console.log(n);
  return "A" + recur(n-1);
}

recur()

最终结果是:

10
9
8
7
6
5
4
3
2
1
"AAAAAAAAAA"

我希望它为函数的每个实例返回 A,因为我认为函数定义中的每个语句都会为函数的每个实例调用,如下所示:

10
"A"
9
"A"
8
"A"
7
"A"
6
"A"
5
"A"
4
"A"
3
"A"
2
"A"
1
"A"

所以重申一下为什么函数没有像我预期的那样返回 A,我误解了函数的运行模式是什么?

【问题讨论】:

    标签: javascript recursion


    【解决方案1】:

    这样解决可能有助于您的理解:

    recur(5) = "A" + recur(4)
             = "A" + ("A" + recur(3))
             = "A" + ("A" + ("A" + recur(2)))
             = "A" + ("A" + ("A" + ("A" + recur(1))))
             = "A" + ("A" + ("A" + ("A" + ("A" + recur(0)))))
             = "A" + ("A" + ("A" + ("A" + ("A" + ""))))
             = "A" + ("A" + ("A" + ("A" + ("A"))))
             = "A" + ("A" + ("A" + ("AA")))
             = "A" + ("A" + ("AAA"))
             = "A" + ("AAAA")
             = "AAAAA"
    

    所以recur(5) 返回"AAAAA"。您应该能够扩展此推理以表明 recur(10) 返回 "AAAAAAAAAA"

    您每次都打印n 的值,一个整数,并且打印每个 递归调用recur 的结果。您最后看到的"AAAAAAAAAA" 是您的控制台(shell、REPL、...)显示您执行的所有内容的结果;在这种情况下,您会在调用 recur() 的末尾看到它,这与 recur(10) 相同。

    如果你想“追踪”函数,你可以将结果赋值给一个变量,然后返回它。试试这个:

    $ node
    > function recur(n=10){
    ...   if(n===0){
    .....     return "";
    .....   }
    ...   let result = "A" + recur(n-1);
    ...   console.log(n, result);
    ...   return result;
    ... }
    undefined
    > recur()
    1 'A'
    2 'AA'
    3 'AAA'
    4 'AAAA'
    5 'AAAAA'
    6 'AAAAAA'
    7 'AAAAAAA'
    8 'AAAAAAAA'
    9 'AAAAAAAAA'
    10 'AAAAAAAAAA'
    

    【讨论】:

      【解决方案2】:

      我假设您在浏览器控制台、节点外壳或类似的东西中执行此操作。代码输出参数的每个值(除了为 0 时)并且根本不输出任何“A”。 shell/console 只是简单地回显函数返回的值;在这种情况下,您对recur() 的顶级调用。顶级调用评估为“AAAAAAAAAA”的原因是每个函数调用都将“A”附加到递归调用的值。 (n===0 的基本情况返回一个空字符串。)

      如果您想每次都打印“A”,则必须将自己的输出语句添加到代码中。 shell 在返回后仍会打印顶级调用的返回值。

      【讨论】:

        【解决方案3】:

        您正在从函数中返回“A”,而不是每次都打印它。新的A 连接到每个递归调用的返回值。对于您想要的结果,您应该这样做:

        function recur(n=10){
          if(n===0){
            return "";
          }
          console.log(n);
          console.log("A");
          return recur(n-1);
        }
        

        【讨论】:

          【解决方案4】:

          尝试运行它,它可能会使正在发生的事情更加直观。

          function recur(n=10){
            if(n === 0){
              return "";
           }
           var recursiveResult = "A" + recur(n-1);
           console.log(n);
           console.log(recursiveResult);
          
           return recursiveResult;
          }
          
          console.log(recur(10));
          

          递归函数不应为递归函数的每个“循环”返回相同的结果。否则,您不需要递归:)。

          【讨论】:

            【解决方案5】:

            避免使用“函数的实例”来表示“函数的调用”。从技术上讲,它们完全不同。代码示例中有一个recur 的实例,它被调用(即调用)了11 次。

            前十个调用都不能返回,直到它们返回的 表达式 ("A" + recur(n-1)')。已评估。第十一次调用首先返回。之前的调用以其调用的相反顺序返回,在它们返回的表达式已完成计算之后。

            【讨论】:

              猜你喜欢
              • 2010-11-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-06-28
              • 1970-01-01
              • 2023-03-31
              • 2016-06-13
              相关资源
              最近更新 更多