3

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

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

任何信息将不胜感激!

4

1 回答 1

6

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

“他们使用对象身份”是一种简化;完整的故事是 ES Maps 和 Sets 使用SameValueZero算法来确定相等性。

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

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

于 2017-06-14T09:23:24.993 回答