外观
Set 和 Map 解决什么问题?
Set 存不重复的值,用 Object.is 的近亲规则比较(NaN 等于自己,+0 等于 -0)。Map 的键可以是任意值,包括对象,不会像普通对象那样把键都变成字符串。
原理
js
const set = new Set([1, 1, 2])
set.size // 2
const map = new Map()
const user = { id: 1 }
map.set(user, "admin")对象当键时比的是引用,不是深比较。两个长得一样的对象是两把钥匙。
WeakSet 和 WeakMap 的键必须是对象,并且是弱引用。不能遍历,也没有 size。用来给 DOM 或组件实例挂私有数据,实例没了,记录可以回收。
和普通对象比:Map 保持插入顺序,键的类型不受限,频繁增删更合适。对象适合键是已知字符串的结构、需要 JSON 序列化的数据。Map 不能直接 JSON.stringify 成键值,要先变成数组。
追问
怎么用 Set 做交并差?
并集 [...new Set([...a, ...b])]。交集是 a 里 b.has 的那些值。差集同理。值是对象时,这是引用相等,不是深相等。
WeakMap 为什么不能遍历?
键可能在你遍历的同时被回收。不暴露枚举,垃圾回收才不必为了「还有人能列出键」而留着对象。
易错点
- 对象键看引用。每次
map.get({})都是新键。 Set里的对象不会按字段去重。- 把
Map当普通对象点属性,数据不在那些属性上。