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语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...
随机推荐
- Dart http库
推荐下我写的一个http库ajanuw_http 最基本的获取数据 import 'package:http/http.dart' as http; main(List<String> a ...
- HANNAH WHITE:从Facebook谈坚持
HANNAH WHITE于1993年毕业于加州斯坦福大学,被美国多家知名杂志评为最值得关注经济管理学杰出人才,2006年-2009年担任Doll资本管理公司部门主管,2009年-2013年担任Doll ...
- HTTP 协议的前世今生
尽人事,听天命.博主东南大学研究生在读,热爱健身和篮球,正在为两年后的秋招准备中,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 C ...
- Linux下安装mysql-5.7.28详细步骤
一.下载Mysql 下载地址:https://downloads.mysql.com/archives/community/ 二.环境配置 检测系统是否自带Mysql # rmp -qa|grep m ...
- Ajax的基本用法
1.介绍 2.基本用法 2.1原生写法 $.ajax({ url: url, //是否是异步请求,默认是 // async: false, //请求方式,默认是get //type:'get', // ...
- 搭建Elasticsearch可视化界面 Kibana
前言 每一个版本的es都有一个对应的Kibana版本,建议和es相同版本,官网地址: 点击进入下载地址 步骤 1.解压 tar -zxvf kibana-7.2.0-linux-x86_64 2.修改 ...
- win10 查看已保存的wifi密码
netsh wlan show profile name="WIFINAME-Test" key=clear C:\windows\system32> C:\window ...
- POJ1852-换向思考
蚂蚁碰撞后反向与穿越的时间一样. 穷竭搜索---->想象力 #include<stdio.h> int main(void){ int n,len,ansNum,mintime,ma ...
- Flask:数据库管理
为什么不使用SQL语句,而使用ORM框架管理数据库?首先,在python程序中嵌入原生SQL语句,不方便维护,ORM框架使用面向对象思想,使用较方便:第二,如果更换底层数据库引擎,ORM框架不需要修改 ...
- c++移动构造
下面随笔给出c++移动构造. 在现实中有很多这样的例子,我们将钱从一个账号转移到另一个账号,将手机SIM卡转移到另一台手机,将文件从一个位置剪切到另一个位置--移动构造可以减少不必要的复制,带来性能上 ...