Javascript 为什么ES6会削弱&x27;它不是可枚举的吗?

Javascript 为什么ES6会削弱&x27;它不是可枚举的吗?,javascript,ecmascript-6,enumerable,weakmap,Javascript,Ecmascript 6,Enumerable,Weakmap,在我重新使用JavaScript(及相关)之前,我已经做了很多ActionScript3,在那里他们有一个Dictionary对象,它有弱键,就像即将推出的WeakMap一样;但是AS3版本仍然可以像普通的泛型对象一样枚举,而WeakMap没有.keys()或.values() AS3版本允许我们装配一些非常有趣和有用的构造,但我觉得JS版本有点有限。为什么呢 如果flashvm可以做到这一点,那么是什么阻止浏览器做同样的事情呢?我读到它是如何“不确定”的,但这是一种观点,对吗?这是一种折衷。如

在我重新使用JavaScript(及相关)之前,我已经做了很多ActionScript3,在那里他们有一个Dictionary对象,它有弱键,就像即将推出的WeakMap一样;但是AS3版本仍然可以像普通的泛型对象一样枚举,而WeakMap没有
.keys()
.values()

AS3版本允许我们装配一些非常有趣和有用的构造,但我觉得JS版本有点有限。为什么呢


如果flashvm可以做到这一点,那么是什么阻止浏览器做同样的事情呢?我读到它是如何“不确定”的,但这是一种观点,对吗?

这是一种折衷。如果引入支持可枚举性的对象字典,则有两个与垃圾收集相关的选项:

  • 将密钥项视为强引用,以防止对用作密钥的对象进行垃圾收集

  • 使其成为弱引用,允许在每次其他引用消失时对其密钥进行垃圾收集


  • 如果你这样做了,你会非常容易地将大型物体泄漏到到处的记忆中,从而射中自己的脚。另一方面,如果使用选项2,您的密钥字典将取决于应用程序中的垃圾收集状态,这将不可避免地导致无法跟踪错误。

    最终找到了真正的答案:

    弱映射的一个关键特性是无法枚举其密钥。这对于防止攻击者观察共享弱映射对象的环境中其他系统的内部行为是必要的。如果可以从API中发现集合中项目的数量或名称,即使这些值不存在,WeakMap实例可能会创建一个以前不可用的侧通道


    我认为这个结论很好:“因为引用很弱,WeakMap键是不可枚举的(也就是说,没有方法给你一个键列表)。如果是,列表将取决于垃圾收集的状态,引入非确定性。”这并不是说规则无法定义,但是,如果不允许操作从实现开始(有几个相互竞争的实现),就可以完全回避这个问题。当然,这是有道理的,但标准委员会有点软弱(呵呵)。我仍然希望能有一些见解,解释为什么可计算性不够重要,不足以成为必需的特性。@bernstein,你没有。弱映射用于缓存实现和类似的事情,应用程序的其他部分知道映射中可能存在的键。什么?不,不是。这不是关于基本地图,而是一个非常具体的Weakmap问题。引用的项没有回答这个问题,就像这里的其他答案一样,它忽略了一个事实,即AS3版本可以很好地处理非确定性。@Pointy键必须是对象,而不能是原始数据类型,这一事实使得大多数用例无法将WeakMap用作缓存。web缓存使用URL(字符串),DAO类使用OID(整数)作为缓存的键。这两种用例都不可能将对象作为键。同样,正如OP和其他注释中所描述的:AS3的弱键仍然是可枚举的。它工作得很好,可以在不阻塞GC的情况下收集/关联值。然后,您可以循环键来处理尚未收集的键。这是非确定性行为,这是我解释的第2种情况,也是创建另一个答案中描述的侧通道的原因。谢谢。很多因此,这是一个误称,它应该被命名为secretkey和weakmap。任何参加过SE 101的人都会开始哭泣。这个答案假定“在共享弱映射对象的环境中”——但这是常见的吗-我以前从没听说过。此外,为什么这是必要的-如果是,只需创建WeakMap实例自己的弱指针的特殊内部集合,正如WeakMap对象的名称和定义(它是一个map so集合)所示,因此,如果存在/必须共享,那么实现WeakMap实例来创建自己的集合似乎没有问题。所以我看不出答案(现在?)为什么。这令人失望。无法列举弱集合确实限制了它的用途。我认为这实际上不是它。我认为这更多的是为了能够观察GC。如果您允许枚举weakmap,那么开发人员将面临一种不确定性,因为他们现在可以观察GC和内存,而atm则不能。看起来JavaScript在未来将最终获得真正的WeakReference实现!通过将两者结合起来,这将实现一个可移植的WeakMap。(为WeakMap中的每个键创建一个WeakRefs数组,然后通过迭代键并将每个键与in-WeakMap值组合进行迭代)