现在,Javascript有称为
WeakMap
和WeakSet
的类,其中键是弱引用。为什么这些实例不能被迭代,即不能使用WeakMap#entries
进行迭代?请注意:这不是重复的问题。另一个问题问“如何”,而这个问题问“为什么”。WeakMap
和WeakSet
的类,其中键是弱引用。为什么这些实例不能被迭代,即不能使用WeakMap#entries
进行迭代?请注意:这不是重复的问题。另一个问题问“如何”,而这个问题问“为什么”。MDN解释如下:
如果是这样的话,列表将取决于垃圾回收的状态,引入不确定性。
但您可能想知道这到底意味着什么。
首先,垃圾回收是不确定的。JavaScript程序可能会被垃圾回收器在运行环境自行决定的情况下进行垃圾回收。
现在想象一下我们有以下程序:
const weakMap = new WeakMap();
const key1 = { data: 123 };
weakMap.set(key1, "value");
weakMap.set({ data: 456 }, "value");
for (const [key, value] of weakMap) { // This does not actually work, of course
console.log(`${key} is ${value}`);
}
您期望这个程序会产生什么结果?
我们无法确定,因为实际上由{ data:456 }
创建的对象只会在我们的映射中被引用。因此,该条目将被垃圾回收器删除。但是我们不能确定(甚至有点不太可能),当迭代它时,垃圾回收器已经从地图中删除了它。另一方面,它确实可能已经删除了它。
该程序将表现出不可预测的行为,因此不允许使用。
与Map对象的一个不同之处在于,WeakMap键不可枚举(即没有方法可以给您提供键列表)。如果它们是这样的话,列表将取决于垃圾回收的状态,引入了非确定性。
此外,WeakMap#entries
会创建对对象的额外引用,从而防止垃圾回收并破坏WeakMap
的目的。