Map 用作 Hash Map
ES6 给我们带来了 Map
,它更适合当做 hash map 的用例。
首先,它并不像 Object
那样只允许 key 为 string 和 symobol,Map
的 key 支持任何数据类型。
可是如果你使用
Map
为对象存储元数据,应该使用WeakMap
取而代之以此避免内存泄漏。
更重要的是,Map
为用户自定义和内置对象属性提供了清晰的界限,使用一个额外的方法 Map.prototype.get
获取条目。
Map
同样也提供了更人性化的方法,Map
默认就可迭代,意味着你可以轻松的与 for...of
一起使用,同样使用嵌套的解构获取第一个条目。
const [[firstKey, firstValue]] = map
与 Object
对比,Map
为各种常见任务提供了具体的方法:
Map.prototype.has
检查一个给定条目的存在,与对象上的Object.prototype.hasOwnProperty
/Object.hasOwn
对比还是方便许多。Map.prototype.get
返回与提供的 key 相关的值。可能会有人觉得比对象上的.
和[]
稍显笨重。然后它为用户自定义的数据和内置的方法提供了清晰的界限。Map.prototype.clear
可以清除Map
上的所有条目且比delete
操作更快。
性能
在 JavaScript 社区中似乎有一种共同的认知:Map
比 Object
快,在多数情况下,有些人在从 Object
切换到 Map
时看到了性能的提升。
从我在磨人的 LeetCode 中刷题的经验中似乎更加确认了这个观点:LeetCode 使用了大量的数据来对你的解决方案做测试用例,若你的答案花费了太长时间则会超时。像这种问题一般在你使用 Object
时出现几次,而 Map
则没有。
可是,我相信只简单的说 Map
比 Object
快很笼统,肯定有一些细微的差别需要我去发现。因此,我创建了一个小应用来运行一些基准测试。
基准测试的实现细节
这个应用有一个表格用来展示分别对 Object
和 Map
作用插入、迭代和删除的速度。
插入和迭代的性能是以每秒来测量的,我写了一个工具方法 measureFor
用来重复执行目标函数,直到设定的最小阈值(就是传入的 duration
值)。它返回的是每秒函数执行的平均次数。
function measureFor(f, duration) {let iterations = 0;const now = performance.now();