开发者

javascript for loop variable and recursion

I have an issue where I have recursion inside of a for loop:

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

Obviously because JavaScript does not have block scope, the same i variable is getting modified each time the function is called. What is the best way to remedy this? Assume regular EcmaScript 3 and I can't use JavaScript 1.7 "let".

I know this has been asked before, but the other questions don't seem to show recursion, they sho开发者_运维百科w one function call where a closure could be used.


Cache the length of the array so you would have the following:

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

You should always cache especially when you're dealing with HTMLCollections.


Just use Crockford's walkTheDOM function:

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

You pass in the root node and the function that you want to run for each node, like so:

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

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

Live demo: http://jsfiddle.net/VKWTt/


Was this facing issue, like during recursion of a function the variable values got replaced. the recursion was inside for loop, so the variables inside the for loop where modified.

Use var to declare variables that are modified at recursion.


I think you example should work. The variable i is declared local, so when you recurse a new 'i' is used.

Javascript does global and local variables!


You've already defined 'i' as a variable in a broader scope ;)


I'm a little confused. i is declared locally and so it's not the same i variable getting modified. Tested on this very page:

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>]


This worked for me.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜