首页 > 解决方案 > 在孩子上设置父母 - 循环引用

问题描述

我有两个类,Quest并且Task,它们都扩展了Event. 当Quest被实例化时,它调用它的父类在实例上实例Event化多个。这些将属于实例。TasksQuestTasksQuest

这个小提琴更简洁地说明了我的意思。这是一个无休止的循环引用task.parent.task.parent.task.parent...,对于复杂的对象,我担心性能的影响。

当某些事件发生时,孩子Tasks需要告诉他们的父母。Quest因此,当实例化Quest并因此实例化 时Tasks,我通过了,this所以孩子知道它属于谁:

new childEventClass(eventObj, this));

这里明显的问题是您现在有一个无限循环,将子项设置在父项上,将父项设置在子项上,现在又包括子项,等等。 Console.logTask的父项,您会得到:

Quest {
  id: 1,
  children: [
     Task: {
        id: 1,
        parent: Quest {
           id: 1,
           children: [
              Task: {
                id: 1,
                etc...
              },
              ...
           ]
        },
        ...
     },
     ...
  ]
}

你怎么能避免这种情况?

其他文件:

this.quest = new Quest(quest);

课程:

class Event {
    constructor(args, childEventClass, childEventClassName) {
        if (childEventClass && childEventClassName && args[childEventClassName] && args[childEventClassName].length > 0) {
            this.children = args[childEventClassName].map(eventObj => new childEventClass(eventObj, this));
        }
    }
    ...
}

class Quest extends Event {
    constructor(args) {
        super(args, Task, 'tasks');
    }
};

class Task extends Event {
    constructor(args, parent) {
        super(args, Activity, 'activities');
        this.parent = parent;
    }
};

class Activity extends Event {
    constructor(args, parent) {
        ...
    }
};

标签: javascriptoopecmascript-6

解决方案


这是一个无休止的循环引用,对于复杂的对象,我担心会影响性能。

不,它没有。它与这些对象是否复杂无关。

因此,当实例化 Quest 并因此实例化 Tasks 时,我通过this所以孩子知道它属于谁

这是设置您需要的循环引用的好方法。

这里明显的问题是您现在有一个无限循环,将子项设置在父项上,将父项设置在子项上,现在再次包含子项

…但它没有设置它们或尝试再次创建它们,所以不,你没有任何循环。您的代码终止。

Console.log任务的父级,你得到……</p>

不是问题。是的,您可以递归地扩展这些引用。这就是它们被称为循环引用的原因——你可以像绕着一个圆圈跑一样遍历它们。但如果你不这样做,也没有坏处。


推荐阅读