能介绍一下Set、Map、WeakSet、WeakMap之间的区别吗?

 2024-02-12 03:03:29  阅读 0

我是在看小红书的时候看到这个关键词的。 我第一次看到的时候觉得没什么用。 因为我的知识有限,但其实还是有点用处的。 不知道有多大(快跑)

更多信息请查看知友个人网站:一口奶盖

希望这篇文章可以让你对Map有一个更好的认识,或者说帮助你了解Map和

本文首先从Map开始,然后

1. 为什么要地图? 1. 传统的对象结构

Map本质上是键值对的集合。 与传统的对象结构相比,传统对象只能使用字符串作为键名,这在使用上受到了很大的限制。 这也是新地图的原因之一。

const data = {};
// element 为节点对象
const element = document.querySelector(".node");
console.log(element); // 输出 div.node 对象
// 将对象转化成字符串输出 [object HTMLDivElement]
console.log(element.toString()); 
// 用点操作符不能有空格,所以采用中括号的形式给对象赋值
data[element] = 'objectData'
// 输出 objectData,说明在对象中存在[object HTMLDivElement]键名
console.log(data['[object HTMLDivElement]']);

在上面的代码中,我们创建了一个对象,并使用节点对象作为其键名,并进行了代码测试。 首先我们验证获取到的节点是一个对象,然后确认方法转换后的结果。 使用这个value作为key名,成功输出了value值。

设置可以组什么词_设置可以删除吗_可以设置两个key的map

通过上面的测试,确定传统对象的键名会通过方法转换为字符串类型。

注意:我们访问对象成员时,键名有空格时不能使用点访问,如data.ab c

这是错误的。我们需要以data['ab c']的形式来访问它

2. 地图结构

Map 类似于对象,但键名称不限于字符串。 可以说,结构体提供了键值对应关系,Map结构提供了值值对应关系。 因此,使用map结构实际上比传统对象要好。

// 1. 通过new Map来创建dataMap容器
const dataMap = new Map();
// 2. 获取节点对象,作为测试数据
const element = document.querySelector(".node");
// 3. 通过 set 方法给 dataMap 中指定键和对应的值
dataMap.set(element,'objectData');
// 4. 通过 get 来从 dataMap 中获取键名对应的值
console.log(dataMap.get(element));
// 5. 揭开面目
console.log(dataMap);

从上面的代码我们可以清楚地看到第8行获取值的时候直接传入了对象。

可以成功获取对应的值,最后打印时验证申诉语句。

设置可以组什么词_可以设置两个key的map_设置可以删除吗

成功地使用对象作为键名,弥补了传统对象的缺点。

3、地图的特点 地图默认不包含任何key,所有key都是自己添加的。 与原型链不同,原型链有一些默认键。

Map 的键可以是任何类型的数据,甚至是函数。

通过size属性可以轻松获取Map中键值对的数量,需要手动计算。

Map在频繁添加或删除键值对的场景下表现更好。

4.什么时候用Map添加与默认键值名称冲突的键值,又不想更改名称,什么时候使用Map用其他数据类型做键值,什么时候使用Map有很多键值对,并且需要计算数量,当需要频繁使用Map添加或删除键值对时,请使用Map 2.Map实例属性和方法

上面我们接触到了Map的各个API,简单说一下

1套

set方法将键名对应的键值设置为value,然后返回整个Map结构。 如果设置的key已经存在,则更新value值,否则重新生成key。

可以设置两个key的map_设置可以删除吗_设置可以组什么词

还可以使用链式写法设置多组数据

设置可以组什么词_设置可以删除吗_可以设置两个key的map

成功输出如下:

设置可以组什么词_设置可以删除吗_可以设置两个key的map

2. 得到

通过get方法读取key对应的key值。 如果传入的键值不存在,则返回。

设置可以删除吗_设置可以组什么词_可以设置两个key的map

控制台成功输出ljc

3.有

判断传入的key是否存在于当前Map对象中。 该方法返回一个布尔值。

设置可以组什么词_设置可以删除吗_可以设置两个key的map

上面的代码中,如果name存在,则返回true,如果sex不存在,则返回false。

4.

删除传入的key,返回true,如果删除失败,返回false

设置可以组什么词_设置可以删除吗_可以设置两个key的map

5. 清除

清除所有成员,无返回值

设置可以删除吗_设置可以组什么词_可以设置两个key的map

比较清除前后的结果。 请注意,clear 没有返回值!

设置可以删除吗_设置可以组什么词_可以设置两个key的map

3. 遍历方法

可以使用for...of循环和两个方法。由于Map实例维护了键值对的插入顺序,因此可以根据插入顺序进行遍历。

用于...的

for...of 可以遍历带有接口的数据结构

地图。()

Map实例中有一个迭代器,可以按照插入顺序生成[key, value]形式的数据。

我们可以通过方法获取这个迭代器,并使用for...of进行遍历操作

可以设置两个key的map_设置可以删除吗_设置可以组什么词

设置可以删除吗_可以设置两个key的map_设置可以组什么词

也可以如下遍历,得到每一项的数组

设置可以组什么词_设置可以删除吗_可以设置两个key的map

并且由于是默认的迭代器,所以可以直接对Map实例进行扩展操作或者直接使用map

可以设置两个key的map_设置可以组什么词_设置可以删除吗

使用扩展操作

设置可以删除吗_设置可以组什么词_可以设置两个key的map

地图。()

可以使用遍历map.()的方法来遍历map容器的属性值。

设置可以组什么词_设置可以删除吗_可以设置两个key的map

地图.keys()

可以使用map.keys()来遍历键名

设置可以删除吗_可以设置两个key的map_设置可以组什么词

使用()回调遍历

设置可以删除吗_可以设置两个key的map_设置可以组什么词

通过回调遍历地图

4.Map类型转换

与map进行类型转换的几种方法

映射到数组

通过展开运算符实现

let map = new Map()
let arr = [...map]

将数组转换为映射

let map = new Map(arr)

映射到对象

使用set通过遍历的方式为对象添加键值对

let obj = {}
for (let [k, v] of map) {
  obj[k] = v
}

将对象转换为地图

for( let k of Object.keys(obj)){
  map.set(k,obj[k])
}

5. 什么是?

众所周知,它是ES6中一种新的集合类型,称为“弱映射”。 它与Map是兄弟关系。 它和Map的区别就在于这个弱字。 API仍然和Map一样(只有set get有)

那么它的真正含义是什么?

这实际上描述了JS中垃圾收集器处理“弱映射”键的方式。

那么为什么应该有呢? 它解决什么问题?这些问题稍后讨论

六、特点

我们先从特点开始

1.只有对象可以用作键名

空除外

设置可以组什么词_设置可以删除吗_可以设置两个key的map

正常添加

可以设置两个key的map_设置可以组什么词_设置可以删除吗

2.键名引用的对象是弱引用

我在这里困惑了很长时间,但这是结构的关键。

这句话不容易理解。 我们首先需要知道强引用和弱引用。

2.1 什么是强引用?

我们先来看看强引用。 这是阮一峰老师书中的例子。

设置可以删除吗_设置可以组什么词_可以设置两个key的map

上面代码中,e1和e2是两个对象,通过arr数组给这两个对象添加了一些文字描述。 但这就形成了arr对e1和e2的引用,而且这个引用是强引用。 差异就体现在这一点上。 当我们不再需要这两个对象时,必须手动删除这个引用,释放arr与这两个对象的引用关系,否则垃圾回收机制不会释放e1和e2占用的内存。 因为,arr仍然有对象的引用!

设置可以删除吗_设置可以组什么词_可以设置两个key的map

麻烦的操作必然会产生问题。 当忘记手动删除引用时,就会导致内存泄漏。

2.2 什么是弱引用?

对于弱引用,百度百科给出的答案:

在计算机编程中,弱引用与强引用相反,是指不能保证其引用的对象不会被垃圾收集器回收的引用。 仅由弱引用引用的对象被视为不可访问(或弱可访问),因此可能随时被回收。

也就是说如果我们可以像这样创建一个弱引用对象

//假设
let obj = new WeakObject()

我们可以静静地等待垃圾车把它拖走,obj引用的对象就会被回收。

如果你还不明白,我们来看看

2.3 弱引用和强引用说明

从一组代码结合两张图来理解

提供强有力的参考

const myMap = new Map()
let my = {
    name: "ljc",
    sex: "男"
}
myMap.set(my, 'info');
console.log(myMap);

可以设置两个key的map_设置可以组什么词_设置可以删除吗

对于弱引用

const myMap = new WeakMap()
let my = {
    name: "ljc",
    sex: "男"
}
myMap.set(my, 'info');
console.log(myMap);

设置可以组什么词_可以设置两个key的map_设置可以删除吗

图1中的数据被my和myMap实例对象引用,引用计数为2。图2中,myMap对my引用的对象建立了弱引用,引用计数为1。

上面我们讲到强引用数据删除时需要手动解引用,而弱引用则可以等待垃圾回收机制自动清除。

弱引用和垃圾收集

设置可以组什么词_设置可以删除吗_可以设置两个key的map

当执行my=null时,my对原始数据的引用会被释放,myMap实例对象与my引用的对象是弱引用关系。 数据的引用计数为0。程序垃圾回收机制会在执行过程中回收引用对象。 如果存在强引用关系,则引用计数为1,不会被垃圾回收机制清除。

一般情况下,会维护一个对键名引用的对象的弱引用,即垃圾回收机制不会考虑这个引用。 只要清除了对该引用对象的所有其他引用,垃圾回收机制就会释放该对象占用的内存。 也就是说,一旦不再需要,里面的键对象和对应的键值对就会自动消失,不需要手动删除引用。

3.不可穿越

因为键名引用的对象具有弱引用关系,所以内部成员会依赖于是否执行垃圾回收机制。 运行前后的成员数量很可能不同,垃圾收集机制的执行情况是不可预测的。 ,因此不可遍历

既然您了解了 的特点,相信您对于“为什么?”已经有了一定的答案。

7、Map和Map的区别相信看到这里你心里已经有了答案。

八、使用场景 1、DOM节点元数据红皮书使用示例

因为不影响垃圾回收,所以可以用来关联元数据

设置可以删除吗_可以设置两个key的map_设置可以组什么词

当执行上述代码时,登录按钮将从 DOM 树中删除。 但是,由于Map与节点对象有强引用关系,所以仍然保存了对按钮的引用,所以会造成内存泄漏。

设置可以删除吗_设置可以组什么词_可以设置两个key的map

因此,当一个节点被删除时,引用计数变为0,等待垃圾收集机制回收。

2. 部署私有属性

使用弱映射将内部属性设置为实例的弱引用对象。 当实例被删除时,私有属性就会消失,因此不会出现内存泄漏。

阮一峰老师的代码示例

设置可以组什么词_可以设置两个key的map_设置可以删除吗

3.数据缓存

当我们需要在不修改原始对象的情况下存储某些属性等,但又不想管理数据时,我们可以使用

可以设置两个key的map_设置可以删除吗_设置可以组什么词

非常感谢您的阅读。 欢迎您提出意见。 如果您有任何疑问,请指出。 谢谢你!

标签: 遍历map 键值

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码