如何打破 TypeScript 中的强引用循环?
在我的实现中,我有一个类似树的结构,包含父对象和子对象。父对象有一个子列表,子对象有一个指向父对象的引用,以便能够轻松地在树中导航。现在我想知道,由于我们这里存在强引用循环(我不清楚 TypeScript 中的弱指针),这样的结构是否会被垃圾回收。
这里有一个(非常简单)的例子来说明这种结构,尽管我相信每个人都能想象出它会是什么样子:
class Symbol {
protected parent: Symbol | undefined;
protected children: Symbol[];
}
对于这种数据结构,推荐的方法是什么?使用(相对)较新的 WeakMap 或 WeakSet 类来引用父对象(听起来很丑陋)吗?
答案#1
表示树的方法有很多,哪一种最好取决于你如何使用你的树结构。
如果你对现在的情况感到满意,并且只关心垃圾回收,那么为什么不为你的节点引入一个remove方法呢?
class MySymbol {
protected parent: MySymbol | undefined;
protected children: MySymbol[];
remove() {
this.children = [];
this.parent && this.parent.childRemoved(this);
}
childRemoved(child: MySymbol) {
this.children.splice(this.children.indexOf(child), 1);
}
}
(请注意,我将 Symbol 改为 MySymbol,否则会出现重复名称错误)
这种方法只在孩子只能有一个父母的情况下有效,否则这需要稍作改变。
编辑
唯一可能给你类似效果的方法是为你的 children 使用 WeakMap。
也可以阅读这里的答案:在 Javascript 中使用 WeakMaps 创建常规弱引用
