起因
为了升高并发时的 API 申请量, 这两天写了个 LRU Cache. 其中用到了 Set 做 AllowList, 来判断 API 是否应该被缓存.
在 MDN 查 API 时, 发现 Set 被归类在 Keyed Collection 中. 始终以来, 下意识感觉 Set 只是 value 惟一的 Array. 应该属于 Indexed Collection. 感觉有些奇怪, 所以就查了下 Set 的实现机制
过程
一开始, 先去 MDN 查的文档, 只说了属于 Keyed Collection, 但没细说为什么. 又去 ecma-international.org, 查 ECMA 规范, 后果也没有明确阐明, 为什么 Set 属于 Keyed Collection. 我一开始还感觉是文档写得不够具体, 起初发现是本人太菜了😂
简略思考了下, 没想通. 就应用魔法武器了. 尽管有点前后不一, 但 copilot 提供了最要害的信息: Hash Table. 下边是 copilot 的答复
在 JavaScript 中,Set 是一种基于哈希表实现的数据结构,用于存储一组惟一的值。Set 属于 ECMAScript 6 中新增的数据类型之一,被归类为 Keyed Collection 类型。
Keyed Collection 是 ECMAScript 6 中新增的一种数据类型,用于存储一组键值对。除了 Set 之外,还包含 Map 和 WeakMap。这些数据类型都具备以下特点:
- 能够应用任意类型的值作为键。
- 能够应用 for…of 循环遍历键值对。
- 能够应用 size 属性获取键值对的数量。
Set 作为 Keyed Collection 的一种,能够应用任意类型的值作为元素,而且每个元素都是惟一的。因而,Set 能够用于实现汇合、过滤反复值等性能。
须要留神的是,Set 和 Map 的实现形式不同,尽管它们都属于 Keyed Collection 类型。Map 是一种键值对的汇合,其中每个键都是惟一的,能够应用键来拜访对应的值。Set 是一种值的汇合,其中每个值都是惟一的,能够应用值来拜访对应的值。
再而后, 就破案了 … 因为 Hash Table 中, 每个元素都有惟一的 key, 用 key 来拜访对应的值. 所以, Set 相当于一个 key-value 雷同的、非凡的 Hash Table, 我认为也能够了解为, 一种 key-value 统一、非凡的 Map
论断
- Set 是基于 Hash Table 实现的「值的汇合」
- 因为 Hash Table 的 key-value 个性, Set 的 key-value 雷同
- Set 相当于一种非凡的 Map
所以, Set 属于 Keyed Collection
┌─────┐
┌─▶│Array│
┌──────────────────┐ │ └─────┘
┌─▶│Indexed Collection│──┤
│ └──────────────────┘ │ ┌───────────┐
│ └─▶│Typed Array│
│ └───────────┘
┌────────────┐ │
│ Collection │──┤ ┌───┐ *
└────────────┘ │ ┌─▶│Map│ *
│ │ └───┘ *
│ │ ┌───────┐ *
│ ┌──────────────────┐ ├─▶│WeakMap│ * ┌───────────────────┐
└─▶│ Keyed Collection │──┤ └───────┘ * │Based on Hash Table│
└──────────────────┘ │ ┌───┐ * └───────────────────┘
├─▶│Set│ *
│ └───┘ *
│ ┌───────┐ *
└─▶│WeakSet│ *
└───────┘ *
材料
- https://262.ecma-international.org/13.0/#sec-keyed-collections
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide…