资讯专栏INFORMATION COLUMN

《深入理解ES6》笔记——Set集合与Map集合(7)

Charlie_Jade / 2653人阅读

摘要:常被用来检查对象中是否存在某个键名,集合常被用来获取已存的信息。返回一个布尔值,表示该值在中存在与否。集合存放对象的弱引用,当该对象的其他强引用被清除时,集合中的弱引用也会自动被垃圾回收机制回收,追踪成组的对象是该集合最好的使用方式。

Map和Set都叫做集合,但是他们也有所不同。Set常被用来检查对象中是否存在某个键名,Map集合常被用来获取已存的信息。

Set Set是有序列表,含有相互独立的非重复值。 创建Set

既然我们现在不知道Set长什么样,有什么价值,那么何不创建一个Set集合看看呢?

创建一个Set集合,你可以这样做:

let set = new Set();
console.log(set);

//在浏览器控制台的输出结果
Set(0) {}
    size:(...)
    __proto__:Set
    [[Entries]]:Array(0)
    length:0

看起来像个对象,那么现在我们在控制台打印一个对象,对比一下两者有什么不同。

let obj = new Object()
console.log(obj)

//在控制台输出对象
Object {}
    __proto__: 

从输出结果看,Set和Object有明显的区别,反正他们就不是一个东西。

接着,我们看一下Set的原型有哪些:

这里主要介绍几个基础原型的作用,想要了解全部请前往 Set集合之家 查看:

Set.prototype.size
返回Set对象的值的个数。

Set.prototype.add(value)
在Set对象尾部添加一个元素。返回该Set对象。

Set.prototype.entries()
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值的[value, value]数组。为了使这个方法和Map对象保持相似, 每个值的键和值相等。

Set.prototype.forEach(callbackFn[, thisArg])
按照插入顺序,为Set对象中的每一个值调用一次callBackFn。如果提供了thisArg参数,回调中的this会是这个参数。

Set.prototype.has(value)
返回一个布尔值,表示该值在Set中存在与否。

在例子中使用这几个方法测试一下:

let set = new Set();
set.add("haha");
set.add(Symbol("haha"));

console.log(set.size); //2

console.log(set); 
Set(2) {"haha", Symbol(haha)}
    size:(...)
    __proto__:Set
    [[Entries]]:Array(2)
        0:"haha"
        1:Symbol(haha)
    length:2
    
console.log(set.has("haha")) // true

到这里,你会发现Set像数组,又像一个对象,但又不完全是。

迭代Set

Set既然提供了entries和forEach方法,那么他就是可迭代的。

但如果你使用for in来迭代Set,你不能这样做:

for(let i in sets) {
  console.log(i); //不存在
}

for in迭代的是对象的key,而在Set中的元素没有key,使用for of来遍历

for(let value of sets) {
  console.log(value);
}
//"haha"
//Symbol(haha)

//如果你需要key,则使用下面这种方法
for(let [key, value] of sets.entries()) {
  console.log(value, key);
} 
//"haha" "haha"
//Symbol(haha) Symbol(haha)

forEach操作Set:Set本身没有key,而forEach方法中的key被设置成了元素本身。

sets.forEach((value, key) => {
  console.log(value, key);
});
//"haha" "haha"
//Symbol(haha) Symbol(haha)

sets.forEach((value, key) => {
  console.log(Object.is(value, key));
}); 
//true true
Set和Array的转换

Set和数组太像了,Set集合的特点是没有key,没有下标,只有size和原型以及一个可迭代的不重复元素的类数组。既然这样,我们就可以把一个Set集合转换成数组,也可以把数组转换成Set。

//数组转换成Set
const arr = [1, 2, 2, "3", "3"]
let set = new Set(arr);
console.log(set) // Set(3) {1, 2, "3"}

//Set转换成数组
let set = new Set();
set.add(1);
set.add("2");
console.log(Array.from(set)) // (2) [1, "2"]

js面试中,经常会考的一道数组去重题目,就可以使用Set集合的不可重复性来处理。经测试只能去重下面3种类型的数据。

const arr = [1, 1, "haha", "haha", null, null]
let set = new Set(arr);
console.log(Array.from(set)) // [1, "haha", null]
console.log([...set]) // [1, "haha", null]
Weak Set集合

Set集合本身是强引用,只要new Set()实例化的引用存在,就不释放内存,这样一刀切肯定不好啊,比如你定义了一个DOM元素的Set集合,然后在某个js中引用了该实例,但是当页面关闭或者跳转时,你希望该引用应立即释放内存,Set不听话,那好,你还可以使用 Weak Set

语法:

new WeakSet([iterable]);

和Set的区别:

1、WeakSet 对象中只能存放对象值, 不能存放原始值, 而 Set 对象都可以.

2、WeakSet 对象中存储的对象值都是被弱引用的, 如果没有其他的变量或属性引用这个对象值, 则这个对象值会被当成垃圾回收掉. 正因为这样, WeakSet 对象是无法被枚举的, 没有办法拿到它包含的所有元素.

使用:

let set = new WeakSet();
const class_1 = {}, class_2 = {};
set.add(class_1);
set.add(class_2);
console.log(set) // WeakSet {Object {}, Object {}}
console.log(set.has(class_1)) // true
console.log(set.has(class_2)) // true

Map Map是存储许多键值对的有序列表,key和value支持所有数据类型。 创建Map

如果说Set像数组,那么Map更像对象。而对象中的key只支持字符串,Map更加强大,支持所有数据类型,不管是数字、字符串、Symbol等。

// 一个空Map集合
let map = new Map()
console.log(map)

Map的所有原型方法:

对比Set集合的原型,Map集合的原型多了set()和get()方法,注意set()和Set集合不是一个东西。Map没有add,使用set()添加key,value,在Set集合中,使用add()添加value,没有key。

let map = new Map();
map.set("name", "haha");
map.set("id", 10);
console.log(map)
// 输出结果
Map(2) {"name" => "haha", "id" => 10}
    size:(...)
    __proto__:Map
    [[Entries]]:Array(2)
        0:{"name" => "haha"}
        1:{"id" => 10}
    length:2

console.log(map.get("id")) // 10
console.log(map.get("name")) // "haha"

使用对象做key

let map = new Map();
const key = {};
map.set(key, "谁知道这是个什么玩意");
console.log(map.get(key)) // 谁知道这是个什么玩意

Map同样可以使用forEach遍历key、value

let map = new Map();
const key = {};
map.set(key, "这是个什么玩意");
map.set("name", "haha");
map.set("id", 1);
map.forEach((value, key) => {
  console.log(key, value)
})

//Object {} "这是个什么玩意"
//"name" "haha"
//"id" 1

其他Map的使用方法可以前往 Map之家 学习。

Weak Map

有强Map,就有弱鸡Map。

和Set要解决的问题一样,希望不再引用Map的时候自动触发垃圾回收机制。那么,你就需要Weak Map。

let map = new WeakMap();
const key = document.querySelector(".header");
map.set(key, "这是个什么玩意");

map.get(key) // "这是个什么玩意"

//移除该元素
key.parentNode.removeChild(key);
key = null;
总结

Set集合可以用来过滤数组中重复的元素,只能通过has方法检测指定的值是否存在,或者是通过forEach处理每个值。

Weak Set集合存放对象的弱引用,当该对象的其他强引用被清除时,集合中的弱引用也会自动被垃圾回收机制回收,追踪成组的对象是该集合最好的使用方式。

Map集合通过set()添加键值对,通过get()获取键值,各种方法的使用查看文章教程,你可以把它看成是比Object更加强大的对象。

Weak Map集合只支持对象类型的key,所有key都是弱引用,当该对象的其他强引用被清除时,集合中的弱引用也会自动被垃圾回收机制回收,为那些实际使用与生命周期管理分离的对象添加额外信息是非常适合的使用方式。

记得刚开始学习JavaScript的时候,不知道各种数据类型有什么用,如果你现在刚学习Map和Set也是这种不知道能用来干什么的想法,那么,恭喜,他们已经开始走入你的编程生涯,慢慢的你就会熟悉他们。

=> 返回文章列表

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88337.html

相关文章

  • 深入理解ES6笔记(七)Set集合Map集合

    摘要:创建并添加项目可以使用数组来初始化一个,并且构造器会确保不重复地使用这些值使用方法来测试某个值是否存在于中移除值使用方法来移除单个值,或调用方法来将所有值从中移除。属性的初始化将数组传递给构造器,以便使用数据来初始化一个。 主要知识点:Set的基本操作,Weak Set,Map的基本操作,Weak MapshowImg(https://segmentfault.com/img/bVbf...

    loostudy 评论0 收藏0
  • 深入理解ES6中的SetMap数据结构,Map其它数据结构的互相转换

    摘要:学习笔记工作中常用到的语法只是简单提及和,今天有空于是写了这篇文章深入理解中的和数据结构,与其它数据结构的互相转换。的提供了新的数据结构。本身是一个构造函数,用来生成数据结构。 文中的内容主要是来自于阮一峰的《ES6标准入门》(第三版)。《学习ES6笔记──工作中常用到的ES6语法》只是简单提及Set和Map,今天有空于是写了这篇文章──《深入理解:ES6中的Set和Map数据结构,M...

    Cristalven 评论0 收藏0
  • 深入理解ES6笔记——导读

    摘要:最近买了深入理解的书籍来看,为什么学习这么久还要买这本书呢主要是看到核心团队成员及的创造者为本书做了序,作为一个粉丝,还是挺看好这本书能给我带来一个新的升华,而且本书的作者也非常厉害。 使用ES6开发已经有1年多了,以前看的是阮一峰老师的ES6教程,也看过MDN文档的ES6语法介绍。 最近买了《深入理解ES6》的书籍来看,为什么学习ES6这么久还要买这本书呢?主要是看到Daniel A...

    Godtoy 评论0 收藏0

发表评论

0条评论

Charlie_Jade

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<