ES6中的Set、WeakSet、Map、WeakMap数据结构

Set

Set本身是一个构造函数,用来生成Set数据结构,类似数组Array,但是成员的值都是唯一的,没有重复的值

属性方法

size: 返回set实例的成员总数
add(value): 添加某个值,返回Set本身
delete(value): 删除某个值,返回是否删除成功的boolean has(value): 判断是否包含某个值,返回一个boolean
clear():清空Set的所有成员,没有返回值

add方法

let aSets = new Set();
aSets.add(1);// 添加1
aSets.add(2);// 添加2

# 结果{
    
     1,2}

另一种创建Set的方法

let bSet = new Set([1,2,3,4,5]);

如果添加重复的value值,会怎么样

aSets.add(2);
结果:{
    
    1,2}  独一无二的

添加的数值类型,有什么区别

aSets.add('2');

结果:{
    
    1,2,"2"}

size

aSets.size;

// 结果: 2

delete方法

aSets.delete(1);
结果:true

aSets.delete(3)
#结果: false

has方法

aSets.has(1);
#结果:true

clear方法

aSets.clear();

# aSets打印结果是{
    
    }

遍历对象

keys():返回一个键名的遍历器
values(): 返回一个键值的遍历器
entries(): 返回一个键值对的遍历器
forEach(): 使用回调函数遍历每个成员

创建一个Set

let list = new Set(["a","b","c","d"]);

keys()

for(let key of list.keys()){
    
    
     console.log(key);
     // a   b   c   d
}

values()

for(let value of list.values()){
    
    
    console.log(value);
     // a   b   c   d
}

entries()

for(let [key,value] of list.entries()){
    
    
     console.log(key,value);
      // a  a    b  b    c  c    d  d
}

forEach()

list.forEach(function(item){
    
    
      console.log(item);
      // a   b   c   d
})

WeakSet

结构和Set类似,但是有写法区别
1、只能存储对象,其他类型的值不行
2、存储的对象是弱引用,也就是说垃圾回收机制不考虑WeakSet对该对象的引用。换种说法如果一个对象都不再被引用,那么垃圾回收机制会自动回收该对象所占用的内存,不会考虑该对象是否存在于WeakSet中。因此WeakSet是不可遍历的

新建一个WeakSet

let list = new WeakSet([{
    
    a:1,b:2},{
    
    c:3,d:4}]);

属性方法

add(value)方法
delete(value)方法
has(value)方法
不支持clear、size方法
如果增加其他类型的数值,则会报错

list.add(2);
# Uncaught TypeError: Invalid value used in weak set

Map

类似于对象,是键值对的集合,但是key的范围不局限与字符串。各种类型均可以作为key

属性方法

set(key,value): 添加一个键值对
get(key): 获取一个key对应的value值
size: 返回Map结构的成员总数
has(key):判断某个键是否存在Map结构中,返回boolean delete(key): 删除某个指定的键值,返回boolean
clear(): 清除Map结构所有的成员

set

let map = new Map();
map.set("1","a");
map.set("2","b");
map.set("3","c");let map = new Map([["1","a"],["2","b"],["3","c"]]);
# delete
map.delete("1");

# size
map.size;

# has
map.has(1);// true

#clear
map.clear();

遍历方法

keys():返回一个键名的遍历器
values(): 返回一个键值的遍历器
entries(): 返回一个键值对的遍历器
forEach(): 使用回调函数遍历Map每个成员

keys()

for(let key of map.keys()){
    
    
     console.log(key);
     // 1  2  3
}

values()

for(let value of map.values()){
    
    
     console.log(value);
     // a  b  c
}

entries()

for(let [key,value] of map.entries()){
    
    
      console.log(key,value);
}

forEach()

map.forEach(function(value,key){
    
    
     console.log(value,key);
})

Map数据结构的定义

Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。

Map和object的对比

Map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。 也就是说, Object
结构提供了“字符串—值”的对应, Map 结构提供了“值—值”的对应是一种更完善的 Hash
结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。

Map的深入理解

简单的方法set get has delete

const m  = new Map()
const o = {
    
    x:'isX'}

m.set(o,'content')
console.log(m);
m.get(o)
console.log(m);
console.log(m.has(o));
m.delete(o)
console.log(m.has(o));

在这里插入图片描述
作为构造函数,Map 也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。

const m = new Map([
    ['name','lisi'],
    ['age','18']
])

console.log(m.size);//2
console.log(m.has('name'));//true
console.log(m.get('name'));//lisi

WeakMap

和Map类似,区别就是键只能是object类型
键名是对象的弱引用,因此所对应的对象可能会被自动回收,如果对象被回收后,WeakMap自动移除对应的键值对,WeakSet有助于防止内存泄露

属性方法

get(key)
set(key,value)
has(key)
delete(key)

let map = new WeakMap();
map.set({
    
    a:"1"},"a");
map.set({
    
    b:"2"},"b");
map.set({
    
    c:"3"},"c");let map = new WeakMap([[{
    
    a:"1"},"a"],[{
    
    b:"2"},"b"],[{
    
    c:"3"},"c"]]);

WeakMap与Map的区别有两点

首先,WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。

其次,WeakMap的键名所指向的对象,不计入垃圾回收机制。

WeakMap的设计目的在于,有时我们想在某个对象上面存放一些数据,但是这会形成对于这个对象的引用。请看下面的例子

在这里插入图片描述

上面代码中,e1和e2是两个对象,我们通过arr数组对这两个对象添加一些文字说明。这就形成了arr对e1和e2的引用。

一旦不再需要这两个对象,我们就必须手动删除这个引用,否则垃圾回收机制就不会释放e1和e2占用的内存。

WeakMap
就是为了解决这个问题而诞生的,它的键名所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内。因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。
也就是说,一旦不再需要,WeakMap
里面的键名对象和所对应的键值对会自动消失,不用手动删除引用。

WeakMap的专用场合就是,它的键所对应的对象,可能会在将来消失。 WeakMap结构有助于防止内存泄漏。

WeakMap只有四个方法可用:

get()、set()、has()、delete()

WeakMap的经典应用
在这里插入图片描述

myElement是一个 DOM 节点,每当发生click事件,就更新一下状态。我们将这个状态作为键值放在 WeakMap 里,对应的键名就是myElement。一旦这个 DOM 节点删除,该状态就会自动消失,不存在内存泄漏风险。
内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。

弱集合、内存与垃圾回收

Map和Set中对象的引用都是强类型化的,并不会允许垃圾回收, 如果Map和Set中引用了大型对象(不再被使用)

ps: 已经从DOM树中删除的DOM元素,那么其回收代价是昂贵的

从上面可以知道,ES6提供的WeakMap和WeakSet的弱集合,这些集合之所以是“弱的”,是因为它们允许从内存中清除不再需要的被这些集合所引用的对象

猜你喜欢

转载自blog.csdn.net/weixin_43638968/article/details/108939104