WeakMap перевернутый

Есть ли способ создать WeakMap из любых других слабых ссылок в Javascript для хранения пар ключ-значение, где ключ - 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 ответа

Вы можете решить эту проблему, используя WeakRef и FinalizationRegistry.

Вот пример, написанный на 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()

Его необходимо запустить с параметром --expose-gc в среде node.js.

Вы не можете поймать операцию удаления. Что вы могли бы сделать, это инкапсулировать данные в другой объект, например

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
Другие вопросы по тегам