javascript for循环变量和递归

时间:2011-06-21 00:37:28

标签: javascript

我有一个问题,我在for循环中有递归:

function func(node) {
    for(var i = 0; i < node.children.length; i++) {
       func(node.children[i]);
    } 
} 

显然因为JavaScript没有块作用域,所以每次调用函数时都会修改相同的i变量。解决这个问题的最佳方法是什么?假设常规的EcmaScript 3和我不能使用JavaScript 1.7“let”。

我知道之前已经问过,但其他问题似乎没有显示递归,它们显示了一个可以使用闭包的函数调用。

7 个答案:

答案 0 :(得分:11)

缓存数组的长度,以便您拥有以下内容:

function recurse(node) {
    for(var i = 0, count = node.children.length; i < count; i++) {
        recurse(node.children[i]);
    }
} 

在处理HTMLCollections时,您应该始终缓存。

答案 1 :(得分:8)

只需使用Crockford的walkTheDOM函数:

function walkTheDOM(node, func) {
    func(node);
    node = node.firstChild;
    while (node) {
        walkTheDOM(node, func);
        node = node.nextSibling;
    }
}

传入根节点和要为每个节点运行的函数,如下所示:

var root = document.getElementById('wrap');

walkTheDOM(root, function(node) {
    console.log( node.nodeName );
});

现场演示: http://jsfiddle.net/VKWTt/

答案 2 :(得分:5)

这是否面临问题,例如在函数递归期间变量值被替换。递归位于 循环内部,因此循环内的变量会被修改。

使用 var 来声明在递归时修改的变量。

答案 3 :(得分:2)

您已经在更广泛的范围内将'i'定义为变量;)

答案 4 :(得分:1)

我认为你的榜样应该有效。变量i被声明为本地变量,因此当您递归时会使用新的“i”。

Javascript执行全局变量和局部变量!

答案 5 :(得分:0)

我有点困惑。 i在本地声明,因此相同的i变量被修改。在这个页面上进行了测试:

var span = document.getElementsByTagName("span")[0];
function func(node) {
    for(var i = 0; i < node.children.length; i++) {
       console.log([i, node]);
       func(node.children[i]);
    } 
}
func(span);

// returns
// [0, <span id="hlinks-user">...</span>]
// [1, <span id="hlinks-user">...</span>]
// [2, <span id="hlinks-user">...</span>]
// [0, <a href="/users...">...</a>]
// [3, <span id="hlinks-user">...</span>]
// [0, <span title="1 silver...">...</span>]
// [1, <span title="1 silver...">...</span>]
// [4, <span id="hlinks-user">...</span>]
// [0, <span title="7 bronze...">...</span>]
// [1, <span title="7 bronze...">...</span>]
// [5, <span id="hlinks-user">...</span>]

答案 6 :(得分:0)

这对我有用。

 function DragDropChanges(nodeChanged) {
        if (nodeChanged.children != null) {
            for (i = 0; i < nodeChanged.children.length;
                var temp = i;
                DragDropChanges(nodeChanged.children[i]);
                i = temp;
            }
        }
    }