通常,如果我想保留一个充满类的所有已创建实例的数组,我会保留对数组中每个实例的引用,从而在其他地方不再引用这些实例时,防止这些实例被垃圾回收。
这是利用 WeakMap 来维护迭代所有仍然相关的实例的方法,同时又不阻止它们被垃圾收集的一种有意义的方法吗?
const indexMap = new Map<number, number[]>()
const wmap = new WeakMap<number[], Person>()
let nextIndex = 0
class Person {
i: number
constructor() {
this.i = nextIndex++
const id = [this.i]
indexMap.set(this.i, id)
wmap.set(id, this)
}
destroy() {
indexMap.delete(this.i)
}
}
// create 3 instances
new Person()
new Person()
new Person()
// iterate instances
for (const id of indexMap.values()) {
console.log(wmap.get(id))
}
我在想,由于 Person 实例不用作 WeakMap 中的键,它可能不起作用,但我不确定我是否正确理解它,即使在多次阅读有关它和 MDN 文档之后。我也不确定如何实际测试它是否有效。
如果有人可以解释或只是链接到我可以阅读的好东西,那就太棒了。
如果您认为它应该有效,请为我建议一种方法来实际验证它是否有效。如何在代码中测试对象是否存在而不引用它们?哈哈:)
不,这行不通。
wmap
中的键仍然从 indexMap
强烈引用,使 Person
实例保持活动状态,直到您 destroy()
它们为止。但这可以更容易实现:
const map = new Map<number, Person>()
let nextIndex = 0
class Person {
i: number
constructor() {
this.i = nextIndex++
map.set(this.i, this)
}
destroy() {
map.delete(this.i)
}
}
// create 3 instances
new Person()
new Person()
new Person()
// iterate instances
for (const person of map.values()) {
console.log(person)
}