在ES6中,地图和集可以使用对象作为键。但是,由于ES6规范没有规定这些数据结构的底层实现,我想知道现代JS引擎如何存储密钥以保证O(1)或至少sublinear检索?
在像Java这样的语言中,程序员可以明确地提供一个(好的)hashCode方法,该方法可以在密钥空间中均匀地散列密钥,以保证性能。但是,由于JS没有这样的功能,仍然可以假设它们在Maps和Sets实现中使用某种散列仍然是公平的吗?
任何信息将不胜感激!
答案 0 :(得分:4)
是的,该实现基于散列,并具有(摊销的)持续访问时间。
“他们使用对象标识”是一种简化;完整的故事是ES Maps和Sets使用SameValueZero算法来确定相等性。
根据此规范,V8的实现为字符串和数字计算“真实”哈希值,并为对象选择一个随机数作为“哈希”,它将这些对象存储为这些对象的私有(隐藏)属性,以便以后访问。 (这不太理想,未来可能会改变,但现在就是这样。)
使用memoryAddress % keySpace
无法正常工作,因为垃圾收集器会移动对象,并且每次移动任何对象时重新散列所有地图和集都会非常复杂和昂贵。