ES6 映射和集合:如何有效地索引对象键?

ES6 Maps and Sets: how are object keys indexed efficiently?

在 ES6 中,Maps 和 Sets 可以使用 Objects 作为键。然而,由于 ES6 规范没有规定这些数据结构的底层实现,我想知道现代 JS 引擎如何存储密钥以保证 O(1) 或至少 sublinear 检索?

在像 Java 这样的语言中,程序员可以显式提供一个(好的)hashCode 方法,该方法会在键 space 中均匀散列键,以保证性能。然而,由于 JS 没有这样的功能,仍然假设他们在 Maps 和 Sets 实现中使用某种哈希仍然公平吗?

如有任何信息,我们将不胜感激!

是的,该实现基于散列,并且具有(摊销的)恒定访问时间。

"they use object identity" 是一种简化;完整的故事是 ES Maps 和 Sets 使用 SameValueZero 算法来确定相等性。

根据此规范,V8 的实现为字符串和数字计算 "real" 哈希值,并为对象选择一个随机数 "hash",并将其存储为私有(隐藏)属性 在这些对象上以供以后访问。 (这不是很理想,将来可能会改变,但现在就是这样。)

使用 memoryAddress % keySpace 无法工作,因为垃圾收集器会四处移动对象,并且每次可能移动任何对象时重新散列所有映射和集合将非常复杂和昂贵。