简体   繁体   English

javascript中的递归限制如何?

[英]how restricted is recursion in javascript?

I guess its to stop browsers getting nailed all the time by duff code but this: 我想它可以阻止浏览器一直被Duff代码所困扰,但这是:

        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);
                }
            }
        }

produces: 产生:

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

and not the big old mess I get when I do: 而不是我做这些事时得到的旧烂摊子:

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

Am I missing something or is this how you do recursion in JS? 我是否缺少某些东西,或者这是您在JS中进行递归的方式? I am interested in navigating trees using recursion where you need to call the method for each of the children. 我对使用递归导航树感兴趣,您需要为每个孩子调用该方法。

You are using a global variable as loop counter, that's why it only loops completely for the innermost call. 您正在使用全局变量作为循环计数器,这就是为什么它只为最内层调用完全循环。 When you return from that call, the counter is already beyond the loop end for all the other loops. 当您从该调用返回时,对于所有其他循环,该计数器已经超出了循环结束。

If you make a local variable: 如果您创建局部变量:

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

The output is the same number of items as when using a timeout. 输出与使用超时时的项目数相同。 When you use the timeout, the global variable doesn't cause the same problem, because the recursive calls are queued up and executed later, when you have exited out of the loop. 使用超时时,全局变量不会引起相同的问题,因为当您退出循环时,递归调用将排队并在以后执行。

I know what your doing wrong. 我知道你在做什么 Recursion in functions maintains a certain scope, so your iterator (i) is actually increasing in each scope every time the loop runs once. 函数中的递归保持一定范围,因此每次循环运行一次时,迭代器(i)实际上在每个范围中都会增加。

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

Note it is now 'var i = 0' this will stop your iterators from over-writing eachother. 请注意,现在它是“ var i = 0”,这将阻止您的迭代器相互覆盖对方。 When you were setting a timeout, it was allowing the first loop to finish running before it ran the rest, it would also be running off the window object, which may remove the closure of the last iterator. 设置超时时,它允许第一个循环在运行其余循环之前完成运行,它也将在window对象之外运行,这可能会删除最后一个迭代器的关闭。

Recursion is very little restricted in JavaScript. 递归在JavaScript中几乎没有限制。 Unless your trees are very deep, it should be fine. 除非您的树木很深,否则应该没问题。 Most trees, even with millions of elements, are fairly wide, so you get at most log(n) recursive calls on the stack, which isn't noramally a problem. 大多数树,即使具有数百万个元素,都相当宽,因此您最多可以在堆栈上进行log(n)递归调用,这在正常情况下不是问题。 setTimeout is certainly not needed. 当然不需要setTimeout As in your first example, you're right that sometimes you need a guard clause to guarantee that the recursion bottoms out. 就像在第一个示例中一样,您有时会需要保护子句以确保递归达到最低要求,这是对的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM