需要 WeakMap (a, b) -> c

Need WeakMap (a, b) -> c

我有一个 memoized fn,其中 fn 由两个输入引用记忆:

let NewRefCursor = memoized(
    (deref, swap) => refToHash(deref) + refToHash(swap), // memoizer identity fn
    (deref, swap) => new RefCursor(deref, swap)); // the function we are memoizing

我需要的行为是NewRefCursor(a, b) === NewRefCursor(a, b)。当 ab 被垃圾回收时,游标也应该被垃圾回收。

refToHash is another memoized function that uses 这样看到的引用仍然允许 GC。

NewRefCursor 更难以记忆,因为它使用两个参数来确定缓存命中,因此与 WeakMap 不兼容,因此将阻止任何看到的引用被 GC 处理。我对任何形式的欺骗持开放态度,将私有字段附加到输入对象、概率数据结构。这个泄漏需要解决。到目前为止,我唯一的解决方案是向 memoize 添加一个限制缓存大小的参数,并在每个应用程序的基础上调整该参数。恶心。

如果你创建一个二级weak-map(在weakmaps上存储weakmaps),每当第一层的obj被gced时,你就会失去整个第二层(当a被gced时,你会失去b)。如果 b 被 gced,你仍然会有一个 a 的 weakmap,它只会在有另一对(a,某物)时存在。不是最好的实现,但我认为足够了:

function BiWeakMap() {
    this._map = new WeakMap();
}

BiWeakMap.prototype.set = function(key1, key2, value) {

    if (!this._map.has(key1)) {
        this._map.set(key1, new WeakMap());
    }

    this._map.get(key1).set(key2, value);

    return this;

};

BiWeakMap.prototype.has = function(key1, key2) {

    return this._map.has(key1) && this._map.get(key1).has(key2);

};

BiWeakMap.prototype.get = function(key1, key2) {

    return this._map.get(key1) && this._map.get(key1).get(key2);

};

这个概念可以扩展到 n-level 解决方案。这是否解决了您的问题,还是我遗漏了什么?

https://github.com/Dans-labs/dariah/blob/master/client/src/js/lib/utils.js 中查看备忘 它通过构建所有对象参数的 WeakMap 索引以通用方式解决问题。 WeakMap 索引为对象分配唯一的整数,然后可以通过 stringify 将其与其他参数放在一起。