ES6中新增的Set和Map两种数据结构

127 阅读3分钟

Set是一种叫做集合的数据结构,Map是一种叫做字典的数据结构

集合:是由一堆无序的、相关联的且不重复的内容结构【数学中称为元素】组成的组合

字典:是一些元素的集合。每个元素有一个称作key的域,不同元素的key各不相同

共同点:集合、字典都可以存储不重复的值

不同点:集合是以[值 , 值]的形式存储元素,字典是以[键 , 值]的形式存储

Set

类似数组,值唯一,没有重复值

Set 本身是一个构造函数, Set 的实例关于增删改查的方法:

(1) add( )

添加某个值,返回 Set 结构本身

当添加实例中已经存在的元素, Set 不会重复添加

const s = new Set()
s.add(1).add(2).add(2)
console.log(s) // {1,2}

(2) delete( )

删除某个值,返回布尔值

s.delete(1)

(3) has( )

返回一个布尔值,判断该值是否为 Set 的成员

s.has(2)

(4) clear( )

清除所有成员,没有返回值

s.clear()

Map

Map 类型是键值对的有序列表,而键和值都可以是任意类型

Map 本身是一个构造函数, Map 的实例关于增删改查的方法:

(1) size 属性

(2) set( )

(3) get( )

(4) has( )

(5) delete( )

(6) clear( )

(1) size

size 属性返回Map结构的成员总数

const map = new Map()
map.set('foo', true)
map.set('bar', false)
map.size // 2

(2) set( )

设置键名key对应的键值为value,然后返回整个 Map 结构

如果key已经有值,则键值会被更新,否则就新生成该键

同时返回的是当前Map对象,可采用链式写法

const m = new Map();
m.set('edition', 6) // 键是字符串 
m.set(262, 'standard') // 键是数值 
m.set(undefined, 'nah') // 键是 undefined 
m.set(1, 'a').set(2, 'b').set(3, 'c') // 链式操作

(3) get( )

get方法读取key对应的键值,如果找不到key,返回undefined

const m = new Map(); 
const hello = function() {console.log('hello');}; 
m.set(hello, 'Hello ES6!') // 键是函数 
m.get(hello) // Hello ES6!

(4) has( )

has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中

const m = new Map();
m.set('edition', 6); 
m.set(262, 'standard');
m.set(undefined, 'nah');
m.has('edition') // true 
m.has('years') // false 
m.has(262) // true 
m.has(undefined) // true

(5) delete( )

delete方法删除某个键,删除成功,返回true。如果删除失败,返回false

const m = new Map(); 
m.set(undefined, 'nah');
m.has(undefined) // true 
m.delete(undefined)
m.has(undefined) // false

(6) clear( )

clear方法清除所有成员,没有返回值

let map = new Map(); 
map.set('foo', true); 
map.set('bar', false); 
map.size // 2 
map.clear()
map.size // 0

WeakSet和WeakMap

WeakSet

创建WeakSet实例

const ws = new WeakSet()

WeakSet可以接受一个具有 Iterable接口的对象作为参数

const a = [[1, 2], [3, 4]]; 
const ws = new WeakSet(a); 
// WeakSet {[1, 2], [3, 4]}

APIWeakSetSet有两个区别:

  • 没有遍历操作的API
  • 没有size属性

WeackSet成员只能是引用类型,而不能是其他类型的值

let ws=new WeakSet(); 

// 成员不是引用类型 
let weakSet=new WeakSet([2,3]);
console.log(weakSet) // 报错 

// 成员为引用类型
let obj1={name:1} 
let obj2={name:1} 
let ws=new WeakSet([obj1,obj2]);
console.log(ws) //WeakSet {{…}, {…}}

WeakSet里面的引用只要在外部消失,它在 WeakSet里面的引用就会自动消失

WeakMap

WeakMap结构与Map结构类似,也是用于生成键值对的集合 在APIWeakMapMap有两个区别:

  • 没有遍历操作的API
  • 没有clear清空方法
// WeakMap 可以使用 set 方法添加成员 
const wm1 = new WeakMap(); 
const key = {foo: 1}; 
wm1.set(key, 2); 
wm1.get(key) // 2 

// WeakMap 也可以接受一个数组, 
// 作为构造函数的参数 
const k1 = [1, 2, 3]; 
const k2 = [4, 5, 6]; 
const wm2 = new WeakMap([[k1, 'foo'], [k2, 'bar']]); 
wm2.get(k2) // "bar"

WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名

const map = new WeakMap();
map.set(1, 2) 
// TypeError: 1 is not an object! 
map.set(Symbol(), 2) 
// TypeError: Invalid value used as weak map key 
map.set(null, 2) 
// TypeError: Invalid value used as weak map key

WeakMap的键名所指向的对象,一旦不再需要,里面的键名对象和所对应的键值对会自动消失,不用手动删除引用