【问题标题】:Strange result using recursion with while loop使用带有while循环的递归的奇怪结果
【发布时间】:2012-07-10 12:37:30
【问题描述】:

我是 Javascript 的初学者。在自己尝试递归时,我使用 while 循环得到了一些奇怪的结果。并且使用 If 语句得到正确的结果。

这是代码和结果:

var test = function f(n){
    while(n > 0){
        document.write(n);
        f(--n);     
    }
};

test(5);

结果:

5432112113211211432112113211211

使用 If 语句时

var test = function f(n){
    if(n > 0){
        document.write(n);
        f(--n);     
    }
};

test(5);

结果是:

54321

while 的情况下,我无法真正调试它。老实说,这让我在某些时候感到困惑。

【问题讨论】:

  • 那你为什么不直接使用 if 语句呢?
  • 我不明白你的问题是什么。第一个函数按预期工作,尽管我不得不承认它非常奇怪且不直观。
  • 我只是在玩递归。首先我尝试了 While 然后如果,我想知道为什么 while 循环会给出这个结果?
  • @missingno 感谢您的链接。看到和我一样的问题,可惜这里无法调试代码

标签: javascript recursion while-loop


【解决方案1】:

需要注意的重要一点是,每次在f 中运行代码时,都会使用名为nnew 变量创建一个新范围。因此,通过递归调用f,您将添加到作用域链中。您不断添加到作用域链中,直到 n > 0 变为 false。一旦它为假,您就开始向后遍历作用域链,其中存在 other 版本的n。重复该过程,直到所有作用域中的所有n 变量变为0

请注意当我在下面的数字中添加一些空格时出现的模式。每次代码必须沿作用域链向上时,我都会添加一个空格。每组数字代表沿着作用域链向下的代码。

54321 1 21 1 321 1 21 1 4321 1 21 1 321 1 21 1

Here is a jsfiddle that should be helpful. 它打印两个数字:第一个代表您所在的范围,第二个与您在代码中打印的数字相同。查看第一个数字并尝试了解如何为每个范围创建一个新数字。当您稍后在程序中返回该范围时,请尝试考虑 n 的值应该是多少。

【讨论】:

  • 啊,使用 jsfiddle 的解释非常好,谢谢! ..但我有几个问题:1)为什么(5:1)在这里做?为什么它甚至在那里?
  • 1) 请注意,您会一直回到 (0:2) 上的第一个范围。由于 n 仍然大于 0,它再次调用 f(--n),创建一个新范围并传递一个值 1
  • @Rafael 2) 是的,你可以这样想。请记住,它是一个新函数,您使用 var 声明的任何参数或变量都是该函数范围的一部分。一旦您离开该新函数,就会在调用函数处继续执行。
  • @Rafael 3) 使用 if 语句,你仍然沿着作用域链向下,但是当你回来时,f(--n) 之后没有更多代码可以执行,所以你离开了函数并爬回作用域链上的下一个函数。使用 while 循环,一旦返回,while 条件 (n > 0) 会再次测试,如果为真,则继续循环。
  • @Rafael 不客气!感谢您的挖掘,直到您真正了解发生了什么!作为程序员,这会让你走得很远(如果还没有的话)。
【解决方案2】:

5432112113211211432112113211211 你可以看到模式:

5432112113211211
 432112113211211

543211211
  3211211
 43211211
  3211211

543211
   211
  3211
   211
 43211
   211
  3211
   211

etc

这些只是它所经历的所有循环。首先它打印 5,然后拆分为 4,再拆分为 3,以此类推。

【讨论】:

  • 很有趣,但您可以为我调试生成这种模式的代码吗?因为我根本不知道它是怎么回事。我的意思是在n = 0 之后会发生什么?
  • 如果你调用f(0),第一个while循环甚至不会循环一次(因为0>0是假的),所以什么也不会发生。
  • 好吧,该函数内部什么也没有发生,但需要注意的重要一点是,一旦该函数完成,将在调用函数处继续执行,其中n 的值不一定相同。
  • 不完全。 n 的值在函数参数列表中声明,因此没有全局泄漏。此外,标量值得到 passed-by-value 而不是 by-reference 因此,如果您调用 var n = 5; f(n); console.log(n);,它将打印 5,而不是 0;
猜你喜欢
  • 2017-05-19
  • 1970-01-01
  • 2018-10-19
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多