Skip to main content

moregeek program

ES6 新增数据结构,太强了,值得学习-多极客编程

大家好,我是前端人,每日分享前端相关内容!

今天给大家介绍下 ES6 中的 Map、WeakMap、set 和 WeakSet 的详细使用,以及它们的区别!

本篇文章知识点总结如下:

ES6 新增数据结构,太强了,值得学习_ES6

一、Set

ES6 中提供新的数据结构 Set 集合,它类似于数组,但成员的值都是唯一的,集合类似于高中所学的集合,概念是一致的。集合实现了 iterator 接口,所以他可以使用扩展运算符进行展开,也可以使用 for...of 进行遍历。

set 使用:

let s = new Set([ '年终奖是大事', '放假是好事', '放假是好事' ]);
console.log( s ) // set(2) { '年终奖是大事', '放假是好事' }
console.log( typeof s ) // object

new Set 返回的数据是一个对象,它是自动去掉重复项。

集合的属性和方法分别有:

  • size :返回集合元素的个数
  • add :增加一个新元素
  • delete:删除某个元素,返回布尔值
  • has :检测集合中是否包含某元素
  • clear:清空集合

Set 的常见应用:

  • 数组去重:
let arr = [ 1,2,3,4,3,2,1 ]
let res = [ ...new Set(arr) ]
console.log( res ) //[1, 2, 3, 4]
  • 取两个集合的交集
let arr1 = [ 1,2,3,4,3,2,1 ]
let arr2 = [ 1,2 ]
let res = [...new Set(arr1)].filter( item=>new Set(arr2).has(item) )
console.log( res ) //[1, 2]
  • 取两个集合的并集
let arr1 = [ 1,2,3,4,3,2,1 ]
let arr2 = [ 1,2 ]
let res =[ ...new Set([...arr1, ...arr2]) ]
console.log(res ) //[ 1, 2, 3, 4 ]
  • 取差集
let arr1 = [ 1,2,3,4,3,2,1 ]
let arr2 = [ 1,2 ]
let res = [...new Set(arr1)].filter( item=>!new Set(arr2).has(item) )
console.log( res ) //[ 3, 4 ]

Set 数据遍历:

let s1 = new Set()
s1.add("碧根果")
s1.add("夏威夷果")
for(let v of s1){
console.log("v",v)
}
/*
v 碧根果
v 夏威夷果
*/

Set 遍历的方式有很多,我只介绍 for...of ,剩余的可自行查找!

二、Map

ES6 提供了 Map 数据结构,它类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象)都可以当做键,Map 也实现了 iterator 接口,所以也可以使用 for...of 进行遍历,使用扩展运算符展开数据。

Map 的使用:

let m= new Map()
m.set( "name", "我是前端人" )
let key = {
job: "前端工程师"
}
m.set( key, [ "运营", "设计" ] )
console.log(m)

运行结果如图:

ES6 新增数据结构,太强了,值得学习_ECMAScript_02

集合的属性和方法:

  • size :返回集合元素的个数
  • set:给 Map 添加键值对。
  • get:从 Map 中提取值。
  • delete:删除某个元素,返回布尔值
  • has :检测集合中是否包含某元素
  • clear:清空集合

Map 的遍历

let map = new Map([['title','hello world'],['year','2022']]);
map.forEach((value,key,ownerMap)=>{
console.log(value);
console.log(key);
});

hello world
title
2022
year

Map 的应用

假设有一个场景,我们需要存储 DOM 节点的属性以及它的值,我们可能会用到 Object 或者 Map 。在这选择 Map

const m = new Map()
const loginBtn = document.querySelector("#login")
m.set( loginBtn, { disabled: true } )

这样应用的时候会产生一个问题:当用户登录之后,跑到另一个界面,登录按钮被移除,正常来说,这个 DOM 节点应该被垃圾回收清除,但是它被 loginBtn 变量引用,loginBtn 作为 key 被 Map 引用,所以登录 DOM 节点会保留在内存中,白白占用空间。此时就需要引入 WeakMap 。

三、WeakMap

WeakMap 的 key 只能是 Object 实例化的对象或者派生类的对象,如果不是的话,则会报错,WeakMap 对象的 value 值 可以是任意类型数据。

WeakMap 使用

let wm = new WeakMap()
wm.set( {},'value' )

弱键:WeakMap 的 key 都是对象或者派生类的对象,目的是为了让这个 key 被弱持有。这些对象都是弱引用,不会干扰到垃圾回收。当 WeakMap 中的键在 WeakMap 之外不存在引用时,该键值对会被移除。

Map 中的实例把 Map 替换成 weakMap:

const vm = new WeakMap()
const loginBtn = document.querySelector("#login")
vm.set( loginBtn, { disabled: true } )

作为 WeakMap 对象的 key 不会被正式引用,也就是说 loginBtn 变量不被 vm 引用,这时垃圾回收器就可以把这个 loginBtn 变量和登录DOM节点都给干掉,释放内存空间。

WeakMap 的 key 不算正式引用,随时可以被回收清除掉,因此 WeakMap 不提供迭代功能。对于 size 属性和 clear 方法,由于它们需要先迭代遍历所有的 key 才能计算得到,所以 size 和 clear 无法使用。

WeakMap 的 API 与 Map 对象基本都是一样的,除了没有 size 属性和 clear 方法。

四、WeakSet

WeakSet 对于 Set 而言,就像 WeakMap 对于 Map 一样。

在存放对象时,实际上是存放的是对象的引用,即 Set 也被称之为 Strong Set 。如果所存储的对象被置为 null ,但是 Set 实例仍然存在的话,对象依然无法被垃圾回收器回收,从而无法释放内存。

let set = new WeakSet();
let key = {};
set.add(key);
console.log(set.has(key)); //true
set.delete(key);
console.log(set.has(key)); //false

注意:WeakSet 构造器不接受基本类型的数据,只接受对象。同样的可以使用可迭代的对象或数组,来作为构造器参数,来创建 WeakSet 。

WeakSet 的 API 与 Set 对象基本都是一样的,除了没有 size 属性和 clear 方法。

五、总结之间的区别

5.1、对于 WeakSet 和 Set 之间的区别:

  • WeakSet 没有 size 和 clear 。
  • WeakSet 无法暴露出任何迭代器。
  • WeakSet 不可迭代,因此不能使用 for...of 遍历
  • WeakSet 实例,弱调用了 add 方法时传入非对象参数,会抛出异常。在 has 和 delete 方法传入非对象的参数返回 false。

对于 WeakMap 和 Map 之间的区别与上边 WeakSet 和 Set 的区别类似。不再赘述。

5.2、Set 与 Map 之间的共性及区别:

  • Set 和 Map 都是一种数据结构,但是 Set 是一个无重复的有序列表,类似于数组,而 Map 是有序的键值对集合,类似于对象。
  • 都将通过 Object.is() 方法来判断其中的值不相等,保证 Set 和 Map 移除重复值。Set 无法随机访问其中的值,只能通过 has 判断某个值是否存在。而 Map 使用 get 提取任意键对应的数据。
  • Map 和 Set 都可以随意的实例中添加数据,Set 使用的是 add ,而 Map 使用的 set 方法。其他的 API 都相同。

©著作权归作者所有:来自51CTO博客作者web前端人的原创作品,请联系作者获取转载授权,否则将追究法律责任
ES6 新增数据结构,太强了,值得学习
https://blog.51cto.com/u_13953650/5009623

uniapp和小程序如何分包,详细步骤(图解)#yyds干货盘点#-多极客编程

 一、小程序分包 每个使用分包小程序必定含有一个主包。所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分。 在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示 目前小程序分包大小有以下限制: 整个小程序所有分包大小不超过 20M 单个分包/主包

老大说:谁要再用double定义商品金额,就自己收拾东西走-多极客编程

先看现象涉及诸如float或者double这两种浮点型数据的处理时,偶尔总会有一些怪怪的现象,不知道大家注意过没,举几个常见的栗子:典型现象(一):条件判断超预期System.out.println( 1f == 0.9999999f ); // 打印:falseSystem.out.println( 1f == 0.99999999f ); // 打印:true 纳尼?典型现象(二)

带你掌握Visual Studio Code的格式化程序-多极客编程

摘要:Visual Studio Code 中的所有语言都可以使用其中一种自动格式化程序进行格式化,并且 Python 扩展还支持 linter。本文分享自华为云社区《​​Visual Studio Code 整理和格式化​​》,作者: Yuchuan。Visual Studio Code 中的所有语言都可以使用其中一种自动格式化程序进行格式化,并且 Python 扩展还支持 linter。Lin

【北亚数据恢复】raid5磁盘阵列在进行热备盘同步数据过程中,硬盘掉线导致raid崩溃的数据恢复案例-多极客编程

环境:15块硬盘组成的raid5阵列;raid5阵列上层存储结构是一个xfs裸分区,起始位置是0扇区。故障:阵列中一块硬盘出现故障掉线,热备盘上线同步数据的过程中又有其他硬盘掉线,导致数据同步过程中断,阵列崩溃,数据丢失。管理员联系北亚数据恢复中心寻求帮助。硬盘物理故障检测:北亚数据恢复工程师对这个阵列中的所有硬盘进行了物理故障检测,发现最先离线的硬盘发现了大量的坏道,后来同步数据过程中掉线的硬盘

面试官:Redis持久化机制是怎样的?-多极客编程

大家好,我是Jensen。我们先来看这么一段面试场景——面试官:你们项目缓存技术用到了什么缓存技术?小帅:Redis面试官:那么问一下,Redis缓存技术用到的持久化机制是哪一种机制?小帅:AOF面试官:好吧,回去等通知吧……这个问题,不知道你在面试的时候有没有被别人问过,你是怎么回答的?其实不管你怎么回答都是错的,为什么?请往下看。大家都知道,Redis是我们互联网公司必用的架构技术,在我们业内

#yyds干货盘点#PostgreSQL 14中提升Nested Loop Joins性能的enable_memoize-多极客编程

PostgreSQL 14中提升Nested Loop Joins性能的enable_memoize最近在PG14中发现新增一个配置参数enable_memoize,通过此参数可以提升嵌套循环连接的性能,有人测试性能竟然能提升1000倍!将查询提升1000倍暗示整个语句非常烂,而memoize可能有很大帮助,那么对于普通join是否也有用呢?什么是memoization?memoization表示

#yyds干活盘点# 3 Css3 的背景-多极客编程

一、Css3的背景1.background-size:规定背景图片的尺寸Background-size属性:值说明length设置背景图片高度和宽度。第一个值设置宽度,第二个值设置的高度。如果只给出一个值,第二个是设置为"auto(自动)"percentage将计算相对于背景定位区域的百分比。第一个值设置宽度,第二个值设置的高度。如果只给出一个值,第二个是设置为"auto(自动)"cover此时会

元宵节给网站挂个灯笼-多极客编程

元宵节将至,给网站挂个灯笼,也增加点节日气氛。喜欢的朋友们可以自己复制代码调试一下,样式也可以自己修改。在网上参考了相关代码,实现方式很简单,首先添加一张背景图片,代码实现过程如下:body { background: url("./test.png"); -webkit-background-size: cover; -o-bac

#yyds干货盘点#three.js源码解读-getObjectByProperty方法-多极客编程

1.源码截图getObjectByProperty方法使用了递归getObjectById方法和getObjectByProperty方法都是基于getObjectByProperty方法,所以获取物体的核心方法就是getObjectByProperty2.代码测试稍作修改: 把源码中的this改成为多传递一个参数,方便测试,因为本地不是面向对象的写法,源码中是面向对象的写法// 该方法使用了递归

#yyds干货盘点# 【实用】用 FP 思想将 JS 循环做简单封装~-多极客编程

本篇带来 FP 函数式编程思想在 JS【循环】中的应用。闲言少叙,冲 (づ ̄3 ̄)づ╭~通常,写一个循环:for (let i=9; i<=22; i++) { // do something with i}复制代码或者:let i = 9;while (i <= 22) { // do something with i i++;}复制代码这样写有什么问题吗?说有,也

#yyds干货盘点# HTML总结(一)-多极客编程

 一、HTML简介 1.前端开发三种语言 HTML5                                        网页的结构 CSS3                                         网页的表现 JavaScript                                   网页的行为 2.前端开发三种框架 VUE.JS       Re

#yyds干货盘点# Web Components 系列(八)—— 自定义组件的样式设置-多极客编程

前言 通过前面的学习,对自定义组件的相关概念和知识点也有了一定了解,今天我们就来学习一下给自定义元素及其子元素设置样式的几种方法。 直接给自定义标签添加样式 index.html: <style> my-card{ display: block; margin: 20px; width: 200px; heigh