# SetMap

长久以来,数组Array一直是JavaScript中唯一的集合类型,但是由于是数值型索引而在使用上受限。对于非数值类型索引的集合,就是SetMap

# 基于对象实现的SetMap

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

上述解决方案存在以下一些问题:

  • 对象的属性必须是字符串类型,所以map["5"]map[5]引用的是同一个属性
  • 对象类型会被转换成"[object Object]",会出现错误
  • map中值为False类的值,直接if判断会存在bug,使用in操作符会检索对象的原型,需要保证对象的原型为null

# ES6中的SetWeakSet

Set是一种有序列表,其中含有一些相互独立的非重复值。通过Set集合可以快速访问其中的数据,更加有效的追踪各种离散值

将对象存储在Set中,与存储在变量中完全一样,只要改实例存在,垃圾回收机制就不能释放该对象的内存空间,可以被看做是一个强引用的Set集合。WeakSet则是弱引用集合,只存储对象的弱引用,并且不可以存储原始值,集合中的弱引用如果是对象的唯一引用,该对象可以正常被垃圾回收。

两者的区别

  • WeakSet中,通过add()方法添加非对象参数会报错,has()delete()方法会返回false
  • WeakSet不可迭代,不能用于for-of循环
  • WeakSet不暴露任何迭代器方法(keys()values()),无法通过程序本身来检测其中的内容
  • WeakSet不支持forEach()方法
  • WeakSet不支持size属性