Set 和 Map 主要的应用场景在于 数据重组 和 数据储存
Set 是一种叫做 集合 的数据结构,Map 是一种叫做 字典 的数据结构
Set
Set本身是一个构造函数,用来生成 Set 数据结构。Set 对象允许你储存任何类型的唯一值,无论是原始值或者是对象引用。Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以 keys 方法和 values 方法的行为完全一致。默认遍历器生成函数就是它的 values 方法,可以省略 values 方法,直接用 for...of(value) 循环遍历 Set
特性
- 成员的值都是唯一的,没有重复的值。
- 利用 Set 去除数组重复成员。
- 向 Set 加入值的时候,不会发生类型转换。类似
===的算法判断两个值是否不同,主要的区别是向 Set 加入值时认为 NaN 等于自身,而精确相等运算符认为 NaN 不等于自身。 - keys 方法和 values 方法的行为完全一致。原因是 Set 结构没有键名,只有键值(或者说键名和键值是同一个值)
- 直接用 for...of(value) 循环遍历 Set
- 实现并集(Union)、交集(Intersect)和差集(Difference)。
let set1 = new Set([1, 2, 3])
let set2 = new Set([4, 3, 2])
let intersect = new Set([...set1].filter(value => set2.has(value))) // [2,3]
let union = new Set([...set1, ...set2]) // [1,2,3,4]
let difference = new Set([...set1].filter(value => !set2.has(value))) // [1]WeakSet
WeakSet 结构与 Set 类似,也是不重复的值的集合。WeakSet 对象允许你将弱引用对象储存在一个集合中。
与 Set 的区别
- WeakSet 的成员只能是对象,而不能是其他类型的值。
- WeakSet 中的对象都是弱引用
- WeakSet 没有 size 静态属性
- WeakSet 没有 clear 方法
- WeakSet 没有遍历方法,WebSet 不能遍历
WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。 一个对象若只被弱引用所引用,则被认为是不可访问(或弱可访问)的,并因此可能在任何时刻被回收。
Map
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Set 和 Map 都可以用来生成新的 Map
Map 的插入总是保持着先后顺序(删除了中间元素也会保持顺序),这和传统 Hash 并不一样。传统 Hash 是一种散列结构,元素并不具备顺序性,而 Map 很明显, 后插入的元素就在最后,保持着这种先后顺序。Map 的底层数据结构,使用了
Hash + 链表实现。用 Hash 思想来存储数据,达到 O(1) 的查找时间,用链表思想来维持插入数据的先后顺序。
特性
- Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键
- Map 的键若是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等(
===),Map 将其视为一个键 - Map 的 set 方法返回的是当前的 Map 对象,因此可以采用链式写法。
- Map 结构转数组结构,可用扩展运算符(...)
与 Object 的区别:
Object:
键(属性名)总是被转换为字符串类型。
可以使用
JSON.stringify()直接序列化对象。对象有原型,这意味着对象的属性可能来自其原型链。
Map:
- 可以使用任意类型的值作为键,包括函数、对象、
undefined等。- 不能直接被
JSON.stringify()序列化,需要先将Map转换为对象或数组。- 不使用原型链,每个键都是存储在
Map对象本身中的。
WeakMap
WeakMap 结构与 Map 结构类似,也是用于生成键值对的集合。注意,WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用。
与 Map 的区别
- WeakMap 只接受对象作为键名(null除外),不接受其他类型的值作为键名。
- WeakMap 的键名所指向的对象都是弱引用,不计入垃圾回收机制。
- WeakMap 没有 size 静态属性
- WeakMap 没有 clear 方法
- WeakMap 没有遍历方法,WeakMap 不能遍历
- WeakMap 只有四个方法可用:get()、set()、has()、delete()。
WeakRef
WeakSet 和 WeakMap 是基于弱引用的数据结构,ES2021更进一步,提供了 WeakRef 对象,用于直接创建对象的弱引用。
let target = {};
let wr = new WeakRef(target);上面示例中,target是原始对象,构造函数WeakRef()创建了一个基于target的新对象wr。这里,wr就是一个 WeakRef 的实例,属于对target的弱引用,垃圾回收机制不会计入这个引用,也就是说,wr的引用不会妨碍原始对象target被垃圾回收机制清除。