JavaScript深入理解-Set、Map、WeakSet和WeakMap
Set
Set 对象允许储存任何类型的唯一值,无论是原始值或者是对象引用
本质:构造函数,用来生成 Set 数据结构
描述
Set 对象是值的集合,你可以按照插入的顺序迭代它的元素。Set 中的元素只会出现一次,即 Set 元素是唯一的。
相当于集合,可以进行并集交集运算。
值的相等
对于原始数据类型(boolean,number,string,null,undefined),如果储存相同值则只保存一个,对于引用类型,引用地址完全相同则只会存一个。
- +0 与-0 在存储判断唯一性的时候是恒等的,所以不可以重复。
- undefined 和 undefined 是恒等的,所以不可以重复。
- NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个不能重复。
属性方法
- size 属性:返回集合元素个数(类似于数组的长度 length)
- add(value)方法:想集合中添加一个元素。如果添加的元素已存在,则不会进行操作。
- delete(value)方法:从集合中删除元素 value
- has(value)方法:判断 value 是否在合集中,返回 true 或者 false
- clear()方法:清空集合
- forEach()方法:根据集合中元素的插入顺序,依次执行提供的回调函数
应用场景
数组去重,交集,并集,差集等等
//数组去重
...new Set([1,1,2,2,3])
//并集
let arr1 = [1, 2, 3]
let arr2 = [2, 3, 4]
let newArr = [...new Set([...arr1, ...arr2])]
//交集
let arr1 = [1, 2, 3]
let arr2 = [2, 3, 4]
let set1 = new Set(arr1)
let set2 = new Set(arr2)
let newArr = []
set1.forEach(item => {
set2.has(item) ? newArr.push(item) : ''
})
console.log(newArr)
//差集
let arr1 = [1, 2, 3]
let arr2 = [2, 3, 4]
let set1 = new Set(arr1)
let set2 = new Set(arr2)
let newArr = []
set1.forEach(item => {
set2.has(item) ? '' : newArr.push(item)
})
set2.forEach(item => {
set1.has(item) ? '' : newArr.push(item)
})
console.log(newArr)
Map
Map 对象保存键值对,并且能够记住键的原始插入顺序,任何值(对象或者原始值)都可以左右一个键或者一个值
描述:
一个 Map 对象在迭代时会根据对象中元素的插入顺序来进行,一个
for of循环在每次迭代后会返回一个形式为[key,value]的数组
键的相等
对于原始数据类型(boolean,number,string,null,undefined),如果储存相同值则只保存一个,对于引用类型,引用地址完全相同则只会存一个。
- +0 与-0 在存储判断唯一性的时候是恒等的,所以不可以重复。
- undefined 和 undefined 是恒等的,所以不可以重复。
- NaN 与 NaN 是不恒等的,但是只能存一个不能重复。
Map 和 Object 的区别
| Map | Object | |
|---|---|---|
| 额外的键 | Map 默认情况下不包含任何键,只包含插入的键 | 一个 Object 有一个原型,原型链上的键名有可能和自己在对象上设置的键名产生冲突,ES5 可以适用 Object.create(null),创建一个没有原型的对象 |
| 键的类型 | 一个 Map 的键可以是任意值,包括函数,对象或者任意基本类型 | 一个 Object 的键必需是一个 String 或者 Symbol |
| 键的顺序 | Map 中的 key 是有序的,因此当迭代的时候,一个 Map 对象以插入的顺序返回键值 | 一个 Object 的键是无序的 |
| Size | 通过 size 属性获取 | Objec 的键值只能手动计算 |
| 迭代 | 可迭代,可以直接被迭代 | 需要某种方式获取到键才能被迭代 |
| 性能 | 在频繁增删键值对的场景下表现更好 | 未作出优化 |
属性方法
- size 属性:返回字典长度(类似于数组的长度 length)
- values()方法:返回一个可迭代对象,包含按顺序插入 Map 对象中每个元素的 value 值
- set(key,value)方法:向字典中添加新元素
- get(key)方法:通过键查找特定数值并返回
- has(key)方法:判断字典中是否存在键 key
- delete(key)方法:通过键 key 从字典中移出对应的数据
- clear()方法:清空字典
- forEach()方法:根据集合中元素的插入顺序,依次执行提供的回调函数
遍历
var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");
for (const [key, value] of myMap) {
console.log(key, value);
}
myMap.forEach((value, key) => {
console.log(value, key);
});
转换
var arr = [
[1, 2],
[3, 4],
[5, 6],
];
var map = new Map(arr);
console.log(map); //Map { 1 => 2, 3 => 4, 5 => 6 }
console.log(Array.from(map)); //[ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ]
复制
let mapV=newMap(map)
WeakSet
WeakSet 对象允许将弱引用对象存在一个集合中
WeakSet 和 Set 区别:
- WeakSet 只能储存对象引用,不能存放值,而 Set 对象都可以
- WeakSet 对象中储存的对象值都是被弱引用的,即垃圾回收机制不考虑 WeakSet 对该对象的引用,如果没有其他的变量或者属性引用这个对象值,则这个对象将会被垃圾回收掉。(不考虑该对象还存在与 WeakSet 中),所以 WeakSet 对象里有多少个成员元素,取决于垃圾回收机制有没有运行,运行前后成员个数可能不一致,遍历结束之后,有的成员可能取不到,被垃圾回收了。因此 ES6 规定,WeakSet 对象是无法被遍历的,也没有办法拿到它包含的所有元素。
属性:
constructor:构造函数
方法:
- add(value)方法:在 WeakSet 中添加一个元素。如果添加的元素已存在,则不会进行操作。
- delete(value)方法:删除元素 value
- has(value)方法:判断 WeakSet 对象中是否包含 value
- clear()方法:清空所有元素
WeakMap
WeakMap 对象是一组键值得集合,其中的键是弱引用。注意:键必需是弱引用,而值可以是任意。
注意:WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用。
WeakMap 和 Map 区别:
WeakMap 中,每个键对自己所引用对象的引用都是弱引用,在没有其他引用和该键引用同一对象,这个对象将会被垃圾回收,相对应的 key 则变成无效的,所以,WeakSet 的 key 是不可枚举的。
属性:
constructor:构造函数
方法:
- set(key,value)方法:设置一组 key 关联对象
- delete(key)方法:移出 key 的关联对象
- has(value)方法:判断 WeakSet 对象中是否包含 value
- get(key)方法:返回 key 关联对象,没有则返回 undefined
总结
- Set
- 成员唯一,无序且不会重复
- 类似于数组集合,键值和键名是一致的(只有键值。没有键名)
- 可以遍历,方法有 add,delete,has
- WeakSet
- 只能存储对应引用,不能存放值
- 成员都是弱引用,会被垃圾回收机制回收
- 不能遍历,方法有 add,delete,has
- Map
- 键名唯一不可重复
- 类似于集合,键值对的集合,任何值都可以作为一个键或者一个值
- 可以遍历,可以转换各种数据格式,方法 get,set,has,delet
- WeakMap
- 只接受对象为键名,不接受其他类型的值作为键名,键值可以是任意
- 键名是拖引用,键名所指向的对象,会被垃圾回收机制回收
- 不能遍历,方法 get,set,has,delete
JavaScript深入理解-Set、Map、WeakSet和WeakMap的更多相关文章
- SE6新特性之集合Set、Map、WeakSet和WeakMap详解
SE5的时候我们经常用数组或者类数组对象来操作数据,而对于一些使用惯了java之类语言的集合的开发人员来说,总有少了点什么的感觉,SE6提供Set和Map这两个集合.不仅从根本上为一些问题提供了解决方 ...
- es6学习笔记--新数据结构Set,Map以及WeakSet,WeakMap
在javascript中,存储数据的方式大部分就是以数组或者对象形式存储的,es6出现了4种新集合Set,Map,WeakSet,WeakMap来存储数据,简化了编程. 集合--Set 类似于数组,但 ...
- Javascript中理解发布--订阅模式
Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 如何实现发布--订阅模式? 发布---订阅模式的代码封装 如何取消订阅事件? 全局--发布订阅对象代码封装 理解模块间通信 回到 ...
- 第一百二十九节,JavaScript,理解JavaScript库
JavaScript,理解JavaScript库 学习要点: 1.项目介绍 2.理解JavaScript库 3.创建基础库 从本章,我们来用之前的基础知识来写一个项目,用以巩固之前所学.那么,每个项目 ...
- 《javascript个人理解,个人整理。》
万事开头难. 本人做前端工程师,已几年,没有特别大的,已文字方式去做总结. 前段时间,早已经想好,但是迟迟没有去下笔!好在现在陆陆续续的写下去. 我知道这是一个很大的工程,但是我还是想做下去,不为别的 ...
- 百度地图JavaScript API经纬度查询-MAP
百度地图JavaScript API经纬度查询-MAP-ABCDEFGHIJKMHNOPQRSTUVWXYZ: 搜索:<input type="text" size=&quo ...
- 【转】Javascript中理解发布--订阅模式
Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时 ...
- JavaScript深入理解sort()方法
一. 基本用法 let arr1 = [3, 5, 7, 1, 8, 7, 10, 20, 19] console.log(arr1.sort()) // [1, 10, 19, 20, 3, 5, ...
- javascript深入理解js闭包(转)
javascript深入理解js闭包 转载 2010-07-03 作者: 我要评论 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...
随机推荐
- 为什么建议选择居住在墨尔本CBD以南2公里内
英国房地产公司PAUL ADAMS ARCHITECT ,简称PPA(公司编号:07635831)成立于2011年,是一家成立近十年的老牌房地产公司.PAA公司一直有着自己的房地产理念,秉持房子是用来 ...
- DBA 的效率加速器——CloudQuery v1.3.2 上线!
嘿,兄弟,我们好久不见,你在哪里 嘿,朋友,如果真的是你,请打声招呼 我说好久不见,你去哪里 你却对我说,我去江湖 我去看 CloudQuery v1.3.2,看看新增了哪些好用的小功能! 一.自动/ ...
- Python元组拆包捡到8倍镜快准狠
元组拆包 元组是不可变列表,列表是通过索引取值的,元组也是: tuple_test = (1, 2, 3) a = tuple_test[0] b = tuple_test[1] c = tuple_ ...
- jQuery编写组件的几种方式
原文链接:https://w.cnblogs.com/xiao-xi/p/8572471.html 三种方式: 1.通过$.extend()来扩展jQuery 2.通过$.fn 向jQuery添加新的 ...
- C语言柔性数组和动态数组
[前言]经常看到C语言里的两个数组,总结一下. 一.柔性数组 参考:https://www.cnblogs.com/veis/p/7073076.html #include<stdio.h> ...
- 微信小程序日期时间选择器(精确到秒)
<picker mode="multiSelector" value="{{dateTime1}}" bindchange="changeDat ...
- AntDesign Pro + .NET Core 实现基于JWT的登录认证
很多同学说AgileConfig的UI实在是太丑了.我想想也是的,本来这个项目是我自己使用的,一开始甚至连UI都没有,全靠手动在数据库里修改数据.后来加上了UI也是使用了老掉牙的bootstrap3做 ...
- 剑指 Offer 58 - I. 翻转单词顺序 + 双指针
剑指 Offer 58 - I. 翻转单词顺序 Offer_58_1 题目描述 方法一:使用Split函数 package com.walegarrett.offer; /** * @Author W ...
- Ubuntu小配置
Ubuntu 拍摄快照 在虚拟机安装好.配置号后各拍摄一次快照,并存储. 可在虚拟机出错后回滚 Root用户 Ubuntu默认不能以 Root用户身份直接登录 因此,正常操作时在需要调用 root权限 ...
- Java流程控制:增强for循环,break&continue,打印99乘法表
增强for循环:java5引入了一种主要用于数组或集合的增强for循环for(声明语句:表达式){//代码句子} 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配.其作用域限定在循环语 ...