2011-09-02 50 views
0

我猜它停止由达夫代码浏览器越来越钉所有的时间,但这样的:JavaScript中递归的限制是多少?

 function print(item) { 
      document.getElementById('output').innerHTML = 
       document.getElementById('output').innerHTML 
       + item + '<br />'; 
     } 

     function recur(myInt) { 
      print(myInt); 
      if (int < 10) { 
       for (i = 0; i <= 1; i++) { 
        recur(myInt+1); 
       } 
      } 
     } 

生产:

0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
10 

,而不是大的老惹我得到当我这样做:

 function recur(myInt) { 
      print(myInt); 
      if (int < 10) { 
       for (i = 0; i <= 1; i++) { 
        var x = myInt + 1; 
        setTimeout("recur("+x+")"); 
       } 
      } 
     } 

我错过了什么,或者这是如何做JS递归?我有兴趣使用递归来导航树,您需要为每个孩子调用方法。

+1

'如果(int <10)'会失败if块并停止递归。这是任何语言的预期行为。 – jiggy

+1

请避免命名变量“int”。虽然它在js中可能是合法的,但这是令人困惑的,因为它是许多其他语言中的保留字。 –

+0

该方法的两个版本应该返回相同的代码,然后他们不会第二个产生大量的数字,因为我期望该方法自动调用两次。对于(i = 0; i <= 1; i ++), – gordatron

回答

4

你正在使用一个全局变量作为循环计数器,这就是为什么它只为最内层调用完全循环。当你从那个呼叫返回时,计数器已经超出了所有其他循环的循环结束。

如果你把一个局部变量:

function recur(int) { 
    print(int); 
    if (int < 10) { 
     for (var i = 0; i <= 1; i++) { 
      recur(int + 1); 
     } 
    } 
} 

输出相同数量的项目使用超时时。使用超时时,全局变量不会导致相同的问题,因为递归调用会排队并稍后执行,此时您已退出循环。

+0

优秀!谢谢!我知道我错过了一些东西......我之前在那里有var,但由于某种原因,我将它删除了! – gordatron

+0

愚蠢,因为我认为当我拿出的var,这将把它放在全球范围不会它..啊,我还在学习JS ;-) – gordatron

1

递归在JavaScript中很少受到限制。除非你的树很深,否则应该没问题。大多数树,即使有数百万个元素,也是相当广泛的,所以在堆栈上最多可以获得log(n)递归调用,这绝不是一个问题。当然不需要setTimeout。就像在你的第一个例子中一样,你是对的,有时你需要一个守卫子句来保证递归最终落空。

+0

这不涉及范围问题,这是他难度的根源 – antlersoft

2

我知道你做错了什么。函数中的递归保持了一定的范围,所以每当循环运行一次时,你的迭代器(i)实际上正在增加每个范围。

function recur(int) { 
      print(int); 
      if (int < 10) { 
       for (var i = 0; i <= 1; i++) { 
        recur(int+1); 
       } 
      } 
     } 

请注意,现在'var i = 0'这会阻止迭代器覆盖彼此。在设置超时时,它允许第一个循环在运行其余部分之前完成运行,它也将从窗口对象运行,这可能会删除最后一个迭代器的关闭。