所以 WeakMap 在键上是弱的......如果我有两个 WeakMap,它们都将 DOM 元素存储为具有一些不同值的键。让我们假设,我们不能将它们结合起来......
如果我们要从 DOM 中删除 DOM 元素,那意味着在某些时候,(键,值)对将从 WeakMap 中删除,对吧?
如果有两个 WeakMap,这仍然有效吗?还是他们阻止对方移除它?
所以 WeakMap 在键上是弱的......如果我有两个 WeakMap,它们都将 DOM 元素存储为具有一些不同值的键。让我们假设,我们不能将它们结合起来......
如果我们要从 DOM 中删除 DOM 元素,那意味着在某些时候,(键,值)对将从 WeakMap 中删除,对吧?
如果有两个 WeakMap,这仍然有效吗?还是他们阻止对方移除它?
如果两个 WeakMap 都持有相同的元素作为key,那么是的,一旦元素从 DOM 中删除,垃圾收集器将可以自由地将其从两个 WeakMap 中删除。
唯一的问题是,如果 WeakMaps 以某种方式持有对元素的循环引用:不,就像 Bergi 所说,不同 WeakMaps 中的循环引用可以很好地收集垃圾,请参阅https://jsfiddle.net/qzj5mxgL/示例。我必须包含代码作为 SE 的示例,以允许我编辑答案,所以:
const delay = ms => new Promise(res => setTimeout(res, ms));
Promise.resolve()
.then(async () => {
const map1 = new WeakMap();
const map2 = new WeakMap();
console.log('not populated yet, check mem usage for jshell.net');
await delay(5000);
for (let i = 0; i < 1e5; i++) {
const elm1 = document.createElement('div');
const elm2 = document.createElement('div');
map1.set(elm1, elm2);
map1.set(elm2, elm1);
}
console.log('populated, check mem usage');
await delay(5000);
console.log('done, check mem usage');
return [map1, map2];
})
.then(async (maps) => {
await delay(1e9);
});
导致内存使用量增加,然后保持高位,然后减少 - 尽管循环引用它们确实得到 GCd。