提示💡
Set(集合、不重复、[值、值])、Map(字典、[键、值]、可以为null等) 、WeakSet 和 WeakMap(外部引用消失、内部引用自动消失、不可以为null等)
如果要用一句来描述,我们可以说
Set
是一种叫做集合的数据结构,Map
是一种叫做字典的数据结构
什么是集合?什么又是字典?
- 集合 :是由一堆无序的、相关联的,且不重复的内存结构【数学中称为元素】组成的组合
- 字典 :是一些元素的集合。每个元素有一个称作 key 的域,不同元素的 key 各不相同
区别?
- 共同点:集合、字典都可以存储不重复的值
- 不同点:集合是以==
[值,值]
的形式存储元素,字典是以[键,值]
==的形式存储
一、Set
Set
是es6
新增的数据结构,类似于数组,但是成员的值都是唯一的,没有重复的值,我们一般称为集合
Set
本身是一个构造函数,用来生成 Set 数据结构
增删改查
Set
的实例关于增删改查的方法:
- add()
- delete()
- has()
- clear()
add()
添加某个值,返回 Set
结构本身
当添加实例中已经存在的元素,set
不会进行处理添加
delete()
删除某个值,返回一个布尔值,表示删除是否成功
has()
返回一个布尔值,判断该值是否为Set
的成员
clear()
清除所有成员,没有返回值
遍历
Set
实例遍历的方法有如下:
关于遍历的方法,有如下:
- keys():返回键名的遍历器
- values():返回键值的遍历器
- entries():返回键值对的遍历器
- forEach():使用回调函数遍历每个成员
Set
的遍历顺序就是插入顺序
keys
方法、values
方法、entries
方法返回的都是遍历器对象
forEach()
用于对每个成员执行某种操作,没有返回值,键值、键名都相等,同样的forEach
方法有第二个参数,用于绑定处理函数的this
let set = new Set([1, 4, 9]);
set.forEach((value, key) => console.log(key + ' : ' + value))
// 1 : 1
// 4 : 4
// 9 : 9
扩展运算符和 Set
结构相结合实现 数组或字符串去重
实现并集、交集、和差集
二、Map
Map
类型是键值对的有序列表,而键和值都可以是任意类型
Map
本身是一个构造函数,用来生成 Map
数据结构
增删改查
Map
结构的实例针对增删改查有以下属性和操作方法:
- size 属性
- set()
- get()
- has()
- delete()
- clear()
size
size
属性返回 Map 结构的成员总数。
set()
设置键名key
对应的键值为value
,然后返回整个 Map 结构
如果key
已经有值,则键值会被更新,否则就新生成该键
同时返回的是当前Map
对象,可采用链式写法
get()
get
方法读取key
对应的键值,如果找不到key
,返回undefined
has()
has
方法返回一个布尔值,表示某个键是否在当前 Map 对象之中
delete()
delete
方法删除某个键,返回true
。如果删除失败,返回false
clear()
clear
方法清除所有成员,没有返回值
let map = new Map();
map.set('foo', true);
map.set('bar', false);
map.size // 2
map.clear()
map.size // 0
遍历
Map
结构原生提供三个遍历器生成函数和一个遍历方法:
- keys():返回键名的遍历器
- values():返回键值的遍历器
- entries():返回所有成员的遍历器
- forEach():遍历 Map 的所有成员
遍历顺序就是插入顺序
三、WeakSet 和 WeakMap
WeakSet
创建WeakSet
实例
const ws = new WeakSet();
WeakSet
可以接受一个具有 Iterable
接口的对象作为参数
在API
中WeakSet
与Set
有两个区别:
- 没有遍历操作的
API
- 没有
size
属性
WeakSet
只能成员只能是引用类型,而不能是其他类型的值
WeakSet
里面的引用只要在外部消失,它在 WeakSet
里面的引用就会自动消失
WeakMap
WeakMap
结构与Map
结构类似,也是用于生成键值对的集合
在API
中WeakMap
与Map
有两个区别:
- 没有遍历操作的
API
- 没有
clear
清空方法
WeakMap
只接受对象作为键名(null
除外),不接受其他类型的值作为键名
WeakMap
的键名所指向的对象,一旦不再需要,里面的键名对象和所对应的键值对会自动消失,不用手动删除引用
举个场景例子:
在网页的 DOM 元素上添加数据,就可以使用WeakMap
结构,当该 DOM 元素被清除,其所对应的WeakMap
记录就会自动被移除
注意❗
注意:
WeakMap
弱引用的只是键名,而不是键值。键值依然是正常引用
下面代码中,键值obj
会在WeakMap
产生新的引用,当你修改obj
不会影响到内部
总结
Set
ES 6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
WeakSet
WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。
- WeakSet 的成员只能是对象和 Symbol 值,而不能是其他类型的值。
- WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
Map
JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。为了解决这个问题,ES 6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,==各种类型的值(包括对象)都可以当作键==。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。
WeakMap
WeakMap
结构与 Map
结构类似,也是用于生成键值对的集合。WeakMap
与 Map
的区别有两点。
WeakMap
只接受对象(==null
除外==)和 Symbol 值作为键名,不接受其他类型的值作为键名。- 其次,
WeakMap
的键名所指向的对象,不计入垃圾回收机制。
WeakMap 就是为了解决忘记删除引用而导致内存泄露的问题而诞生的,它的键名所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内。因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用。
WeakMap 的用途:
- WeakMap 应用的典型场合就是 DOM 节点作为键名。
- WeakMap 的另一个用处是部署私有属性。
WeakRef
WeakSet 和 WeakMap 是基于弱引用的数据结构,ES2021 更进一步,提供了 WeakRef 对象,用于直接创建对象的弱引用。
弱引用对象的一大用处,就是作为 缓存,未被清除时可以从缓存取值,一旦清除缓存就自动失效。