《深入理解ES6》笔记——Set集合与Map集合(7)
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); //2console.log(set); Set(2) {"haha", Symbol(haha)}size:(...)__proto__:Set[[Entries]]:Array(2)0:"haha"1:Symbol(haha)length:2console.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 trueSet和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:2console.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也是這種不知道能用來干什么的想法,那么,恭喜,他們已經開始走入你的編程生涯,慢慢的你就會熟悉他們。
=> 返回文章列表
總結
以上是生活随笔為你收集整理的《深入理解ES6》笔记——Set集合与Map集合(7)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 详解Linux运维工程师打怪升级篇
- 下一篇: Property list types