关于javascript:为什么WeakMaps不可迭代?

Why are WeakMaps not interable?

本问题已经有最佳答案,请猛点这里访问。

Javascript现在具有称为WeakMapWeakSet的类,其中的键被弱引用。

为什么不能迭代这些实例,即使用WeakMap#entires

注意:这不是重复的问题。 另一个问"如何",这问"为什么"。


MDN对此进行了解释

If they were, the list would depend on the state of garbage collection, introducing non-determinism.

但是您可能想知道这到底意味着什么。

首先,垃圾回收是不确定的。 JavaScript程序可以由垃圾回收器根据运行环境的全权酌情决定是否被垃圾回收。

现在假设我们有以下程序:

1
2
3
4
5
6
7
8
9
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 }创建的对象只会在我们的地图中引用。因此,该条目将由垃圾收集器删除。但是我们不能确定(甚至不太可能)垃圾回收器在对其进行迭代时已将其从地图中删除。另一方面,它可能确实已经将其删除。

该程序将表现出不可预测的行为,因此是不允许的。


根据文档:

One difference to Map objects is that WeakMap keys are not enumerable (i.e., there is no method giving you a list of the keys). If they were, the list would depend on the state of garbage collection, introducing non-determinism.

同样,WeakMap#entries将创建对对象的附加引用,从而防止垃圾回收并破坏WeakMap的目的。