什么是Map和weakMap

117 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

前言

我们经常使用键值对的集合其中就有object,但是它只能用字符串作为键,值可以是任意类型,即时是这样,在使用上可能会造成很多的不便。

什么是Map

MDN: Map对象保存键值对,并且能够记住键的原始插入顺序。任何(对象或者基本)都可以作为一个键或者一个值

我觉得就是在object上增加了几个点:

  • 扩展了的类型
  • Map可迭代,object必须借助object.entries()、object.keys()
  • map增加了size属性,可得出集合的成员个数

Map实例的属性和方法

set方法

set方法会根据键去存储值,如果map中含有了这个键就会替换为最新的值,也可以采用链式写法,例子就是如此

const map = new Map();
map.set("a",1).set("{}",2)

get方法

会根据参数作为键从map获取到对应的值,如果没有该值,则返回undefined

const map = new Map();
map.set("a",1).set("{}",2)
console.log(map.get("a"));//1
console.log(map.get("c"));//undefined

如果这里我们给get传入多个参数会发生什么?

const map = new Map();
map.set("a",1).set("{}",2)
console.log(map.get("b",'a'));  // undefined
console.log(map.get("a",'b'));  // 1

由此可见,会以传入个第一个参数作为键,其他会被忽略掉

size属性

size属性会返回map实例的总成员个数

const map = new Map();
map.set("a",1).set("{}",2)
console.log(map.size);//2

has方法

改方法接收参数作为获取map中的键,返回一个布尔值

const map = new Map();
map.set("a",1).set("{}",2)
console.log(map.has("b"))//false
console.log(map.has("a"))//true

delete方法

该方法接收作为键的参数,删除成功返回true,失败则为false

const map = new Map();
map.set("a",1).set("{}",2)
console.log(map.delete("a")); //true
console.log(map.delete("b")); //false

clear方法

呃呃呃,这个就直接清空了,没有返回值

const map = new Map();
map.set("a",1).set("{}",2)
map.clear()
console.log(map);// Map(0) {}

Map提供的遍历方法

keys()

返回键名的遍历器

const map = new Map();
map.set("a",1).set("{}",2)
for (const it of map.keys()) {
     console.log(it); //a,{}
}

注意:不要使用forEach、filter方法

values()

返回值的遍历器

const map = new Map();
map.set("a",1).set("{}",2)
for (const it of map.values()) {
     console.log(it); //1,2
}

entries()

以数组形式返回键值对

const map = new Map();
map.set("a",1).set("{}",2)
for (const it of map.entries()) {
     console.log(it);
     //[ 'a', 1 ]
     //[ '{}', 2 ]
}

forEach()

这个是map提供的可遍历方法

forEach(( value,?key,?map )=>{})

const map = new Map();
map.set("a",1).set("{}",2)
map.forEach((value,key,map)=>{
    console.log(value,key,map);
})

此外还可以接收第二个参数,作为传入回调的this

const map = new Map();
map.set("a",1).set("{}",2)
map.forEach(function(){
    console.log(this); //Map(2) { 'a' => 1, '{}' => 2 }
    console.log(this === map); // true
},map)

Map解决了什么

  • 要添加的键名和Object原型上的键名一致时,需要避免的话可用Map
  • 需要更多数据类型作为键可用Map
  • 需要频繁删减时
  • 需要获取到成员个数时(object也可以用keys等,但是直接调用属性(size可追踪)岂不是很香)
  • 在频繁删减下用Map可能会好一点,具体场景具体分析

什么是WeakMap

  • 只接受对象作为键
  • 弱引用
//无效的
const weakmap = new WeakMap()
weakmap.set("a",1)// Invalid value used as weak map key
//有效的

const weakmap = new WeakMap()
// weakmap.set("a",1)
const obj = {
}
weakmap.set(obj, 1)
console.log(weakmap.get(obj)) //1

注意:这里的键是同一引用,不是看似一样的

至于这个弱引用很难解释,咱们这里就不演示了,大家知道就行,知其然知其所以然