弱引用映射表的反转

3
有没有一种方法可以在Javascript中创建任何其他弱引用的WeakMap,以存储键值对,其中键是String/Number,值是Object。
引用应该像这样工作:
const wMap = new WeakRefMap();
const referencer = {child: new WeakRefMap()}
wMap.set('child', temp.child);
wMap.has('child'); // true
delete referencer.child
wMap.has('child'); //false     

我正在创建一种树形结构,用于跟踪当前范围内仍在使用的引用。

我需要进行大量合并操作,而对于这种情况,递归清理深度嵌套的结构非常低效。

2个回答

2
你可以通过使用WeakRefFinalizationRegistry来解决它。
这里是一个用TypeScript编写的示例:
class InvertedWeakMap<K extends string | symbol, V extends object> {
  _map = new Map<K, WeakRef<V>>()
  _registry: FinalizationRegistry<K>

  constructor() {
    this._registry = new FinalizationRegistry<K>((key) => {
      this._map.delete(key)
    })
  }

  set(key: K, value: V) {
    this._map.set(key, new WeakRef(value))
    this._registry.register(value, key)
  }

  get(key: K): V | undefined {
    const ref = this._map.get(key)
    if (ref) {
      return ref.deref()
    }
  }

  has(key: K): boolean {
    return this._map.has(key) && this.get(key) !== undefined
  }
}

async function main() {
  const map = new InvertedWeakMap()
  let data = { hello: "world!" } as any
  map.set("string!", data)

  console.log('---before---')
  console.log(map.get("string!"))
  console.log(map.has("string!"))

  data = null
  await new Promise((resolve) => setTimeout(resolve, 0))
  global.gc() // call gc manually

  console.log('---after---')
  console.log(map.get("string!"))
  console.log(map.has("string!"))
}

main()

它必须在 Node.js 环境中使用--expose-gc选项来运行。

1
这是一个不错的例子! 自从5年前我在寻找解决方案时,JavaScript已经有了很多新功能=)。 这里是上面代码示例的Codepen链接https://codepen.io/jEnbuska/pen/jOxzZbm - Nabuska

1

你无法捕获删除操作。你可以做的是将数据封装在另一个对象中。

function referenceTo(value){
 this.value=value;
}

所以,如果删除了这个引用,就无法再访问它了。
var somedata=new referenceTo(5)
var anotherref=somedata;
//do whatever
delete somedata.value;
//cannot be accessed anymore
anotherref.value;//undefined

据我理解,这并不能解决删除嵌套结构的问题,当顶层结构被删除时? 附注:我已经修复了示例,之前的是无效的。 我不明白为什么ES6 WeakMap不能将字符串作为键,对象作为值。在日常编程中似乎没有任何价值。 - Nabuska
@nabuska,是的,你可能需要在某个时候进行过滤。 - Jonas Wilms

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接