JS中, Set为什么是带键的集合?
起因
这两天写了个LRU Cache, 用到了Set做AllowList, 来判断API是否应该被缓存.
查MDN时, 发现Set被归类在Keyed Collection中.
下意识中, 总认为Set属于Array的一类, 应该是Indexed Collection. 感觉奇怪, 所以多查了查文档
过程
首先, 看了下MDN的文档、ECMA的文档. 都没有明确说明为什么Set属于Keyed Collection. 我一开始还觉得是文档写的不够详细, 后来发现是自己太菜了
然后, 问copilot chat, 查了下Map、Set的实现. 发现这俩结构, 都是基于Hash Table实现的.
再然后, 就破案了... 因为Hash Table中, 每个元素都有唯一的key, 用key来访问对应的值. 所以, Set相当于一个key-value相同的特殊Hash Table, 我认为也可以理解为, 一种kv一致、特殊的Map
结论
- Set是基于Hash Table实现的「值的集合」
- 由于Hash Table的kv特性, Set的Key-Value相同
- 相当于一种特殊的Map
┌─────┐
┌─▶│Array│
┌──────────────────┐ │ └─────┘
┌─▶│Indexed Collection│──┤
│ └──────────────────┘ │ ┌───────────┐
│ └─▶│Typed Array│
│ └───────────┘
┌────────────┐ │
│ Collection │──┤ ┌───┐ *
└────────────┘ │ ┌─▶│Map│ *
│ │ └───┘ *
│ │ ┌───────┐ *
│ ┌──────────────────┐ ├─▶│WeakMap│ * ┌───────────────────┐
└─▶│ Keyed Collection │──┤ └───────┘ * │Based on Hash Table│
└──────────────────┘ │ ┌───┐ * └───────────────────┘
├─▶│Set│ *
│ └───┘ *
│ ┌───────┐ *
└─▶│WeakSet│ *
└───────┘ *