6

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

 2 years ago
source link: https://blog.51cto.com/u_13953650/5009623
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
大家好,我是前端人,每日分享前端相关内容!

今天给大家介绍下 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 都相同。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK