TypeScript / JavaScript - 这个 WeakMap 'hack' 会按照我的预期工作吗?

问题描述 投票:0回答:1

通常,如果我想保留一个充满类的所有已创建实例的数组,我会保留对数组中每个实例的引用,从而在其他地方不再引用这些实例时,防止这些实例被垃圾回收。

这是利用 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 文档之后。我也不确定如何实际测试它是否有效。

如果有人可以解释或只是链接到我可以阅读的好东西,那就太棒了。

如果您认为它应该有效,请为我建议一种方法来实际验证它是否有效。如何在代码中测试对象是否存在而不引用它们?哈哈:)

javascript typescript garbage-collection weak-references weakmap
1个回答
0
投票

不,这行不通。

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)
}
© www.soinside.com 2019 - 2024. All rights reserved.