Map-WeakMap (es6)

作者: 未路过 | 来源:发表于2022-10-09 08:34 被阅读0次

1 为什么要使Map

es5之前对象的key只能使用字符串,就算不加双引号,在底层实现的时候也是字符串。es6之后,可以使用symbol类型作为key值。总结就是:对象的key只能使用字符串或者symbol。但是对象的value可以是任何类型。

// 1.JavaScript中对象中是不能使用对象来作为key的
const obj1 = { name: "why" }
const obj2 = { name: "kobe" }

 const info = {

[obj1]: "aaa",
[obj2]: "bbb"

 }

 console.log(info)
 //[object Object]: "bbb"

 //当把obj1作为key的时候,会把obj1转换为一个字符串格式
 //obj1转成字符串之后就是[object object]
 console.log(obj1.toString());//[object Object]
 //obj2的key会把前面的覆盖掉

2 Map的基本使用

106.PNG

Map这种数据结构就是允许我们对象类型或者其他类型来作为key的。

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

// 2.Map就是允许我们对象类型来作为key的

const obj1 = { name: "why" }
const obj2 = { name: "kobe" }
const map = new Map()
map.set(obj1, "aaa")
map.set(obj2, "bbb")
console.log(map);
//Map(2) {{…} => 'aaa', {…} => 'bbb'}
map.set(1, "ccc")
//也可以使用基本数据类型作为key

// 构造方法的使用
//作为构造函数,Map 也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。
//new Map([[key, value], [key,value], [key,value]])
const map2 = new Map([[obj1, "aaa"], [obj2, "bbb"], [2, "ddd"]])
console.log(map2)
//Map(3) {{…} => 'aaa', {…} => 'bbb', 2 => 'ddd'}

3 Map的常用方法

107.PNG
//3.常见的属性和方法

//size:返回Map中元素的个数;
const obj1 = { name: "why" }
const obj2 = { name: "kobe" }

const map2 = new Map([[obj1, "aaa"], [obj2, "bbb"], [2, "ddd"]])
console.log(map2.size);//3

//set(key, value):在Map中添加key、value,并且返回整个Map对象;
map2.set("why", "eee")
console.log(map2)//Map(4) {{…} => 'aaa', {…} => 'bbb', 2 => 'ddd', 'why' => 'eee'}
console.log(map2.set("why", "eee"));
//Map(4) {{…} => 'aaa', {…} => 'bbb', 2 => 'ddd', 'why' => 'eee'}

//get(key):根据key获取Map中的value;
console.log(map2.get("why"))//eee
console.log(map2.get(obj1))//aaa

//has(key):判断是否包括某一个key,返回Boolean类型;
console.log(map2.has("why"))//true
console.log(map2.has(obj1))//true

//delete(key):根据key删除一个键值对,返回Boolean类型;
map2.delete("why")
console.log(map2)
//Map(3) {{…} => 'aaa', {…} => 'bbb', 2 => 'ddd'}

//clear():清空所有的元素;
 //map2.clear()
console.log(map2)
//Map(0) {size: 0}


// 4.遍历map
//forEach(callback, [, thisArg]):通过forEach遍历Map;
map2.forEach((item, key) => {
  console.log(item, key);
})

console.log(Object.prototype.toString.call(map2));//[object Map]

for(const item of map2){
  console.log(item);//遍历出来三个数组,每个数组里面放着key和value
  console.log(item[0], item[1]);//item[0]是key,item[1]是value
}

//遍历的同时进行结构
for(const [key, value] of map2){
  console.log(key, value);
}


WeakMap

1 WeakMap的使用

108.PNG
  1. 区别1:

WeakSet只能存放对象

WeakMap的key只能时对象,Map的key可以是对象或者普通数据类型

  1. 区别2:

<img src="img/110.PNG" alt="alt" style="zoom:50%;" />

map时强引用类型,就算obj=null,也不会销毁ox100. 如果换成了weakmap,就变成了弱引用,当obj=null的时候,ox100也会被销毁。

const obj = {name: "obj1"}
// 1.WeakMap和Map的区别二:
const map = new Map()
map.set(obj, "aaa")

const weakMap = new WeakMap()
weakMap.set(obj, "aaa")

// 2.区别一: 不能使用基本数据类型
// weakMap.set(1, "ccc")

// 3.常见方法
// get方法
console.log(weakMap.get(obj))//aaa

// has方法
console.log(weakMap.has(obj))//true
console.log(weakMap)
// delete方法
console.log(weakMap.delete(obj))//true

// WeakMap { <items unknown> }
console.log(weakMap) //因为weakMap不可以遍历

2 WeakMap的应用

109.PNG

14_响应式原理中的WeakMap使用

响应式就是监听对象属性的改变,并且执行某些函数做出对应的响应,这个就是vue3响应式原理里面做的事情。

111.PNG
// 应用场景(vue3响应式原理)
const obj1 = {
  name: "why",
  age: 18
}

function obj1NameFn1() {
  console.log("obj1NameFn1被执行")
}

function obj1NameFn2() {
  console.log("obj1NameFn2被执行")
}

function obj1AgeFn1() {
  console.log("obj1AgeFn1")
}

function obj1AgeFn2() {
  console.log("obj1AgeFn2")
}

const obj2 = {
  name: "kobe",
  age: 30,
  address: "广州市"
}

function obj2NameFn1() {
  console.log("obj1NameFn1被执行")
}

function obj2NameFn2() {
  console.log("obj1NameFn2被执行")
}


function obj2AgeFn1() {
  console.log("obj2AgeFn1")
}

function obj2AgeFn2() {
  console.log("obj2AgeFn2")
}


/* 

我们想要obj1.name属性改变的时候,执行obj1NameFn1和obj1NameFn2
我们想要obj1.age属性改变的时候,执行obj1AgeFn1和obj1AgeFn2
我们想要obj2.name属性改变的时候,执行obj2NameFn1和obj2NameFn2
我们想要obj2.age属性改变的时候,执行obj2AgeFn1和obj2AgeFn2

如何把数据之间通过某种数据结构关联到一起。
想到对应、映射关系。



*/

//weakmap的key只能时对象

// 1.创建WeakMap
const weakMap = new WeakMap()

// 2.收集依赖结构
// 2.1.对obj1收集的数据结构
const obj1Map = new Map()
obj1Map.set("name", [obj1NameFn1, obj1NameFn2]);
obj1Map.set("age", [obj1AgeFn1, obj1AgeFn2]);
weakMap.set(obj1, obj1Map)

// 2.2.对obj2收集的数据结构

const obj2Map = new Map()
obj2Map.set("name", [obj2NameFn1, obj2NameFn2]);
obj2Map.set("age", [obj2AgeFn1, obj2AgeFn2]);
weakMap.set(obj2, obj2Map)

// 3.如果obj1.name发生了改变
// Proxy/Object.defineProperty

obj1.name = "james";
const targetMap = weakMap.get(obj1);
const fns = targetMap.get("name")
fns.forEach(item => item())

/* 

这里为什么要使用weakmap
是因为weakmap时弱引用
当我们想销毁obj1的时候,obj1 = null;
因为weakmap时弱引用,所以会被GC回收和销毁,如果是map的话,就不可以了


*/

112.PNG

相关文章

网友评论

    本文标题:Map-WeakMap (es6)

    本文链接:https://www.haomeiwen.com/subject/vhwiartx.html