ES6 - 新的数据结构Map

220 阅读3分钟

定义

它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。

使用方法

添加数据

let m = new Map()
let obj = {
    name: 'lee'
}
m.set(obj,'Ecma')
console.log(m);

image.png

获取数据

let m = new Map()
let obj = {
    name: 'lee'
}
m.set(obj,'Ecma')
console.log(m.get(obj));                  // Ecma

删除数据

let m = new Map()
let obj = {
    name: 'lee'
}
m.set(obj,'Ecma')                
m.delete(obj)
console.log(m);    // {}

has

let m = new Map()
let obj = {
    name: 'lee'
}
m.set(obj,'Ecma')
console.log(m.has(obj));            // true

数组作为参数

let map = new Map([
    ['name','lee'],
    ['age',18]
])
console.log(map);

image.png

size

let map = new Map([
    ['name','lee'],
    ['age',18]
])
console.log(map.size);                     // 2
console.log(map.has('name'));              // true
console.log(map.get('age'));               // 18
console.log(map.set('name','zhangsan'));   // [{name:'zhangsan'},{age:18}]

遍历Map

遍历的方法和Set差不多,Set中key和value是一样的,但是对于Map来说key和value是不一样的

forEach

let map = new Map([
    ['name','lee'],
    ['age',18]
])
//  注意参数value在前,key在后
map.forEach((value,key) => {console.log(value,key);})   //  lee name  18 'age'

for of

let map = new Map([
    ['name','lee'],
    ['age',18]
])
//  注意参数value在前,key在后
for(let [key,value] of map){
    console.log(key,value);               // name lee age 18
}

keys() && values() && entries()

// for of keys()
let map = new Map([
    ['name','lee'],
    ['age',18]
])

for(let key of map.keys()){
    console.log(key);                  // name age
}

// for of values()
let map = new Map([
    ['name','lee'],
    ['age',18]
])

for(let value of map.values()){
    console.log(value);               // lee 18
}

// for of entries()
let map = new Map([
    ['name','lee'],
    ['age',18]
])

for(let [key,value] of map.entries()){
    console.log(key,value);               // name lee age 18

应用场景

map基本上和对象是一样的,只不过map的key更加的灵活

1.用Map中的has可以判断一个对象中是否有某个属性

// map的API更加灵活,否则用对象来做就要循环判断
let map = new Map()
map.set('school','Beida')
console.log(map.has('school'));

2.用Map中的size判断键值的个数

3.Map 在涉及频繁增删键值对的场景下会有些性能优势

WeekMap

方法

WeakMap结构与Map结构类似,也是用于生成键值对的集合,不同点在于WeekMap的key只支持引用数据类型

let wm = new WeakMap()
wm.set('name','lee')          // Ivalid value used as weak map key

let wm = new WeakMap()
wm.set([1],2)  
wm.set({
    name:'lee'
},'ecma')
console.log(wm);        
   

image.png

另外其他的方法如set、get、has、deleate等方法是一样的,但是WeekMap不支持clear方法,同时也不支持遍历(由于不可遍历当然也不支持size)

同WeekSet一样,它也是弱引用

let wm = new WeakMap()
let ele = document.getElementsByTagName('h1')
wm.set(ele,'info')
console.log(wm.get(ele));            // info

由于它是弱引用,因此它不会被计入垃圾回收机制

对于ele元素,它是引用了节点h1

垃圾回收机制,会记录当前引用的次数,当前ele引用h1节点的次数是1

虽然weekSet引用了元素ele,次数并不会增加,总得次数还是1

如果Dom元素h1被移除掉了

那么垃圾回收机制中的计数器就会变成0

由于WeekSet是弱引用,当垃圾回收机制发现计数器变成了0

就会将h1回收,WeekSetmap中保存的键值对也会自动消失

WeekSetmap的弱引用特性,有助于防止内存泄漏