# Set
和Map
长久以来,数组Array
一直是JavaScript
中唯一的集合类型,但是由于是数值型索引而在使用上受限。对于非数值类型索引的集合,就是Set
和Map
。
# 基于对象实现的Set
和Map
在ES6
发布之前,开发者以及基于非数组对象实现了类似的功能:
// set
var set = Object.create(null)
set.foo = true
if(set.foo){
// do something
}
// map
var map = Object.create(null)
set.foo = 'bar'
var value = map.foo
// do something
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
上述解决方案存在以下一些问题:
- 对象的属性必须是字符串类型,所以
map["5"]
和map[5]
引用的是同一个属性 - 对象类型会被转换成
"[object Object]"
,会出现错误 map
中值为False
类的值,直接if
判断会存在bug
,使用in
操作符会检索对象的原型,需要保证对象的原型为null
# ES6
中的Set
和WeakSet
Set
是一种有序列表,其中含有一些相互独立的非重复值。通过Set
集合可以快速访问其中的数据,更加有效的追踪各种离散值
将对象存储在Set
中,与存储在变量中完全一样,只要改实例存在,垃圾回收机制就不能释放该对象的内存空间,可以被看做是一个强引用的Set
集合。WeakSet
则是弱引用集合,只存储对象的弱引用,并且不可以存储原始值,集合中的弱引用如果是对象的唯一引用,该对象可以正常被垃圾回收。
两者的区别
- 在
WeakSet
中,通过add()
方法添加非对象参数会报错,has()
和delete()
方法会返回false
WeakSet
不可迭代,不能用于for-of
循环WeakSet
不暴露任何迭代器方法(keys()
和values()
),无法通过程序本身来检测其中的内容WeakSet
不支持forEach()
方法WeakSet
不支持size
属性