Skip to content

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 当普通对象点属性,数据不在那些属性上。

相关 ​