【问题标题】:Calling same function in multiple object's context?在多个对象上下文中调用相同的函数?
【发布时间】:2013-05-19 05:17:13
【问题描述】:

我有一个像这样的对象结构;

{
   this.parent = undefined;
   this.children = [];
}

children 中的所有值都具有与上述相同的结构,只是它们的 parent 将引用以它为子对象的对象。

如何在子对象上下文中轻松遍历子对象的所有子对象等?

我知道如何为一个对象循环孩子

obj.children.forEach(function(child) {

});

但是当孩子们可能进入 10-20-30 深层次时,我该如何迭代孩子的所有孩子?

【问题讨论】:

  • 您必须使用recursive 函数。

标签: javascript object foreach


【解决方案1】:

使用recursion

function deepForEach(node, fn) {
    fn(node);
    node.children.forEach(function(child) {
        deepForEach(child, fn);
    });
}

deepForEach(obj, function(obj) {
    console.log(obj);
});

如果我们用通俗易懂的英语表述,它的工作方式就会变得很明显:

  • 如果没有子节点,只需调用带有节点的回调。 (基本情况)
  • 如果有孩子,先处理好我们自己,然后为每个孩子完成整个过程。

这种类型的递归称为preorder traversal

【讨论】:

  • 你能解释一下这里发生了什么吗?
【解决方案2】:

我们将编写一个递归函数。 递归意味着它会再次执行自己:

function iterate(obj) {
    // we will write the parent and the name
    console.log(obj.parent + ' | ' + obj.name);

    // if it has children
    if (obj.children.length) {
        // for each child
        for (var i = 0, l = obj.children.length; i < l; i++) {
            // we will call this function again
            arguments.callee(obj.children[i]);
        }
    }
}

现在如果我们有这样的对象:

var obj = {
    name: 'P1',
    parent: undefined,
    children: [
        {
            name: 'P2',
            parent: 'P1',
            children: []
        },
        {
            name: 'P3',
            parent: 'P1',
            children: [
                {
                    name: 'P4',
                    parent: 'P3',
                    children: [
                        {
                            name: 'P5',
                            parent: 'P4',
                            children: []
                        }
                    ]
                }
            ]
        },
        {
            name: 'P6',
            parent: 'P1',
            children: []
        }
    ]
};

我们可以遍历它:

iterate(obj);

FIDDLE DEMO(在浏览器中打开您的控制台)

【讨论】:

    【解决方案3】:

    标准方法是使用 icktoofay 建议的递归。

    在这种处理中更烦人的是如何管理“块”中的遍历(例如,如果您想在 javascript 程序的“后台”中使用计时器执行此操作)。

    在这种情况下,您可以使用显式堆栈:

    function process_tree(root_node,
                          process_node,
                          chunk_size,
                          completion_call)
    {
        var todo = []; // nodes that need processing
    
        function processOneChunk() {
            for (var j=0; todo.length && j<chunk_size; j++) {
                var x = todo.pop();
                process_node(x);
                for (var i=0; i<x.children.length; i++) {
                    todo.push(x.children[i]);
                }
            }
            if (todo.length) {
                setTimeout(processOneChunk, 0);
            } else {
                completion_call();
            }
        }
    
        todo.push(root_node);
        setTimeout(processOneChunk, 0);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 2013-03-02
      • 1970-01-01
      • 2014-12-17
      相关资源
      最近更新 更多