【问题标题】:Why are WeakMaps not interable? [duplicate]为什么 WeakMaps 不可交互? [复制]
【发布时间】:2018-12-03 04:29:39
【问题描述】:

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

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

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

【问题讨论】:

  • @bergi 这个问题不是重复的。您链接的人问“如何”,而我的人问“为什么” - 请注意,链接的人的答案没有解释“为什么”。
  • 你使用了你不想让这些对象保持活跃的弱结构,即。如果它们还活着,您将它们放在一组中,但您不在乎它们是否还活着。迭代意味着你确实在乎。那里有一种自然的张力。同时允许两者可能会导致错误。
  • @Lolums 抱歉,链接错误。 This one 更合适。

标签: javascript ecmascript-6


【解决方案1】:

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 } 创建的对象只会在我们的地图中被引用。所以这个条目将被垃圾收集器删除。但是我们不能确定(甚至不太可能)垃圾收集器在迭代它时已经从映射中删除了它。另一方面,它可能确实已经将其删除。

这个程序会表现出不可预知的行为,因此是不允许的。

【讨论】:

  • 看起来 JavaScript 将在未来获得 true WeakReference 实现! stackoverflow.com/a/58009243/2441655 这将通过结合两者来启用可迭代的 WeakMap。 (为 WeakMap 中的每个键创建一个 WeakRefs 数组,然后通过遍历键并将每个键与 WeakMap 中的值组合来进行迭代)
【解决方案2】:

根据docs

与 Map 对象的一个​​区别是 WeakMap 键是不可枚举的(即,没有提供键列表的方法)。如果是,则列表将取决于垃圾收集的状态,从而引入非确定性。

另外,WeakMap#entries 会创建对对象的额外引用,从而阻止垃圾收集并破坏WeakMap 的目的。

【讨论】:

  • 这些额外的引用难道不是弱引用吗?
猜你喜欢
  • 2020-04-27
  • 2011-10-10
  • 2018-11-26
  • 1970-01-01
  • 2016-07-03
  • 1970-01-01
  • 2022-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多