Map和Set都叫作集合,可是他们也有所不一样。Set常被用来检查对象中是否存在某个键名,Map集合常被用来获取已存的信息。面试
既然咱们如今不知道Set长什么样,有什么价值,那么何不建立一个Set集合看看呢?编程
建立一个Set集合,你能够这样作:segmentfault
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对象的值的个数。this
Set.prototype.add(value)
在Set对象尾部添加一个元素。返回该Set对象。spa
Set.prototype.entries()
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的全部元素的值的[value, value]数组。为了使这个方法和Map对象保持类似, 每一个值的键和值相等。prototype
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既然提供了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和数组太像了,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]
Set集合自己是强引用,只要new Set()实例化的引用存在,就不释放内存,这样一刀切确定很差啊,好比你定义了一个DOM元素的Set集合,而后在某个js中引用了该实例,可是当页面关闭或者跳转时,你但愿该引用应当即释放内存,Set不听话,那好,你还可使用 Weak Set
语法:
new WeakSet([iterable]);
和Set的区别:
一、WeakSet 对象中只能存放对象值, 不能存放原始值, 而 Set 对象均可以.
二、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
若是说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之家 学习。
有强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也是这种不知道能用来干什么的想法,那么,恭喜,他们已经开始走入你的编程生涯,慢慢的你就会熟悉他们。