摘要:常被用來(lái)檢查對(duì)象中是否存在某個(gè)鍵名,集合常被用來(lái)獲取已存的信息。返回一個(gè)布爾值,表示該值在中存在與否。集合存放對(duì)象的弱引用,當(dāng)該對(duì)象的其他強(qiáng)引用被清除時(shí),集合中的弱引用也會(huì)自動(dòng)被垃圾回收機(jī)制回收,追蹤成組的對(duì)象是該集合最好的使用方式。
Map和Set都叫做集合,但是他們也有所不同。Set常被用來(lái)檢查對(duì)象中是否存在某個(gè)鍵名,Map集合常被用來(lái)獲取已存的信息。
Set Set是有序列表,含有相互獨(dú)立的非重復(fù)值。 創(chuàng)建Set既然我們現(xiàn)在不知道Set長(zhǎng)什么樣,有什么價(jià)值,那么何不創(chuàng)建一個(gè)Set集合看看呢?
創(chuàng)建一個(gè)Set集合,你可以這樣做:
let set = new Set(); console.log(set); //在瀏覽器控制臺(tái)的輸出結(jié)果 Set(0) {} size:(...) __proto__:Set [[Entries]]:Array(0) length:0
看起來(lái)像個(gè)對(duì)象,那么現(xiàn)在我們?cè)诳刂婆_(tái)打印一個(gè)對(duì)象,對(duì)比一下兩者有什么不同。
let obj = new Object() console.log(obj) //在控制臺(tái)輸出對(duì)象 Object {} __proto__:
從輸出結(jié)果看,Set和Object有明顯的區(qū)別,反正他們就不是一個(gè)東西。
接著,我們看一下Set的原型有哪些:
這里主要介紹幾個(gè)基礎(chǔ)原型的作用,想要了解全部請(qǐng)前往 Set集合之家 查看:
Set.prototype.size
返回Set對(duì)象的值的個(gè)數(shù)。
Set.prototype.add(value)
在Set對(duì)象尾部添加一個(gè)元素。返回該Set對(duì)象。
Set.prototype.entries()
返回一個(gè)新的迭代器對(duì)象,該對(duì)象包含Set對(duì)象中的按插入順序排列的所有元素的值的[value, value]數(shù)組。為了使這個(gè)方法和Map對(duì)象保持相似, 每個(gè)值的鍵和值相等。
Set.prototype.forEach(callbackFn[, thisArg])
按照插入順序,為Set對(duì)象中的每一個(gè)值調(diào)用一次callBackFn。如果提供了thisArg參數(shù),回調(diào)中的this會(huì)是這個(gè)參數(shù)。
Set.prototype.has(value)
返回一個(gè)布爾值,表示該值在Set中存在與否。
在例子中使用這幾個(gè)方法測(cè)試一下:
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
到這里,你會(huì)發(fā)現(xiàn)Set像數(shù)組,又像一個(gè)對(duì)象,但又不完全是。
迭代SetSet既然提供了entries和forEach方法,那么他就是可迭代的。
但如果你使用for in來(lái)迭代Set,你不能這樣做:
for(let i in sets) { console.log(i); //不存在 }
for in迭代的是對(duì)象的key,而在Set中的元素沒(méi)有key,使用for of來(lái)遍歷:
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本身沒(méi)有key,而forEach方法中的key被設(shè)置成了元素本身。
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的轉(zhuǎn)換
Set和數(shù)組太像了,Set集合的特點(diǎn)是沒(méi)有key,沒(méi)有下標(biāo),只有size和原型以及一個(gè)可迭代的不重復(fù)元素的類(lèi)數(shù)組。既然這樣,我們就可以把一個(gè)Set集合轉(zhuǎn)換成數(shù)組,也可以把數(shù)組轉(zhuǎn)換成Set。
//數(shù)組轉(zhuǎn)換成Set const arr = [1, 2, 2, "3", "3"] let set = new Set(arr); console.log(set) // Set(3) {1, 2, "3"} //Set轉(zhuǎn)換成數(shù)組 let set = new Set(); set.add(1); set.add("2"); console.log(Array.from(set)) // (2) [1, "2"]
js面試中,經(jīng)常會(huì)考的一道數(shù)組去重題目,就可以使用Set集合的不可重復(fù)性來(lái)處理。經(jīng)測(cè)試只能去重下面3種類(lèi)型的數(shù)據(jù)。
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集合本身是強(qiáng)引用,只要new Set()實(shí)例化的引用存在,就不釋放內(nèi)存,這樣一刀切肯定不好啊,比如你定義了一個(gè)DOM元素的Set集合,然后在某個(gè)js中引用了該實(shí)例,但是當(dāng)頁(yè)面關(guān)閉或者跳轉(zhuǎn)時(shí),你希望該引用應(yīng)立即釋放內(nèi)存,Set不聽(tīng)話(huà),那好,你還可以使用 Weak Set
語(yǔ)法:
new WeakSet([iterable]);
和Set的區(qū)別:
1、WeakSet 對(duì)象中只能存放對(duì)象值, 不能存放原始值, 而 Set 對(duì)象都可以.
2、WeakSet 對(duì)象中存儲(chǔ)的對(duì)象值都是被弱引用的, 如果沒(méi)有其他的變量或?qū)傩砸眠@個(gè)對(duì)象值, 則這個(gè)對(duì)象值會(huì)被當(dāng)成垃圾回收掉. 正因?yàn)檫@樣, WeakSet 對(duì)象是無(wú)法被枚舉的, 沒(méi)有辦法拿到它包含的所有元素.
使用:
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
如果說(shuō)Set像數(shù)組,那么Map更像對(duì)象。而對(duì)象中的key只支持字符串,Map更加強(qiáng)大,支持所有數(shù)據(jù)類(lèi)型,不管是數(shù)字、字符串、Symbol等。
// 一個(gè)空Map集合 let map = new Map() console.log(map)
Map的所有原型方法:
對(duì)比Set集合的原型,Map集合的原型多了set()和get()方法,注意set()和Set集合不是一個(gè)東西。Map沒(méi)有add,使用set()添加key,value,在Set集合中,使用add()添加value,沒(méi)有key。
let map = new Map(); map.set("name", "haha"); map.set("id", 10); console.log(map) // 輸出結(jié)果 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"
使用對(duì)象做key
let map = new Map(); const key = {}; map.set(key, "誰(shuí)知道這是個(gè)什么玩意"); console.log(map.get(key)) // 誰(shuí)知道這是個(gè)什么玩意
Map同樣可以使用forEach遍歷key、value
let map = new Map(); const key = {}; map.set(key, "這是個(gè)什么玩意"); map.set("name", "haha"); map.set("id", 1); map.forEach((value, key) => { console.log(key, value) }) //Object {} "這是個(gè)什么玩意" //"name" "haha" //"id" 1
其他Map的使用方法可以前往 Map之家 學(xué)習(xí)。
Weak Map有強(qiáng)Map,就有弱雞Map。
和Set要解決的問(wèn)題一樣,希望不再引用Map的時(shí)候自動(dòng)觸發(fā)垃圾回收機(jī)制。那么,你就需要Weak Map。
let map = new WeakMap(); const key = document.querySelector(".header"); map.set(key, "這是個(gè)什么玩意"); map.get(key) // "這是個(gè)什么玩意" //移除該元素 key.parentNode.removeChild(key); key = null;總結(jié)
Set集合可以用來(lái)過(guò)濾數(shù)組中重復(fù)的元素,只能通過(guò)has方法檢測(cè)指定的值是否存在,或者是通過(guò)forEach處理每個(gè)值。
Weak Set集合存放對(duì)象的弱引用,當(dāng)該對(duì)象的其他強(qiáng)引用被清除時(shí),集合中的弱引用也會(huì)自動(dòng)被垃圾回收機(jī)制回收,追蹤成組的對(duì)象是該集合最好的使用方式。
Map集合通過(guò)set()添加鍵值對(duì),通過(guò)get()獲取鍵值,各種方法的使用查看文章教程,你可以把它看成是比Object更加強(qiáng)大的對(duì)象。
Weak Map集合只支持對(duì)象類(lèi)型的key,所有key都是弱引用,當(dāng)該對(duì)象的其他強(qiáng)引用被清除時(shí),集合中的弱引用也會(huì)自動(dòng)被垃圾回收機(jī)制回收,為那些實(shí)際使用與生命周期管理分離的對(duì)象添加額外信息是非常適合的使用方式。
記得剛開(kāi)始學(xué)習(xí)JavaScript的時(shí)候,不知道各種數(shù)據(jù)類(lèi)型有什么用,如果你現(xiàn)在剛學(xué)習(xí)Map和Set也是這種不知道能用來(lái)干什么的想法,那么,恭喜,他們已經(jīng)開(kāi)始走入你的編程生涯,慢慢的你就會(huì)熟悉他們。
=> 返回文章列表
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/88337.html
摘要:創(chuàng)建并添加項(xiàng)目可以使用數(shù)組來(lái)初始化一個(gè),并且構(gòu)造器會(huì)確保不重復(fù)地使用這些值使用方法來(lái)測(cè)試某個(gè)值是否存在于中移除值使用方法來(lái)移除單個(gè)值,或調(diào)用方法來(lái)將所有值從中移除。屬性的初始化將數(shù)組傳遞給構(gòu)造器,以便使用數(shù)據(jù)來(lái)初始化一個(gè)。 主要知識(shí)點(diǎn):Set的基本操作,Weak Set,Map的基本操作,Weak MapshowImg(https://segmentfault.com/img/bVbf...
摘要:學(xué)習(xí)筆記工作中常用到的語(yǔ)法只是簡(jiǎn)單提及和,今天有空于是寫(xiě)了這篇文章深入理解中的和數(shù)據(jù)結(jié)構(gòu),與其它數(shù)據(jù)結(jié)構(gòu)的互相轉(zhuǎn)換。的提供了新的數(shù)據(jù)結(jié)構(gòu)。本身是一個(gè)構(gòu)造函數(shù),用來(lái)生成數(shù)據(jù)結(jié)構(gòu)。 文中的內(nèi)容主要是來(lái)自于阮一峰的《ES6標(biāo)準(zhǔn)入門(mén)》(第三版)。《學(xué)習(xí)ES6筆記──工作中常用到的ES6語(yǔ)法》只是簡(jiǎn)單提及Set和Map,今天有空于是寫(xiě)了這篇文章──《深入理解:ES6中的Set和Map數(shù)據(jù)結(jié)構(gòu),M...
摘要:最近買(mǎi)了深入理解的書(shū)籍來(lái)看,為什么學(xué)習(xí)這么久還要買(mǎi)這本書(shū)呢主要是看到核心團(tuán)隊(duì)成員及的創(chuàng)造者為本書(shū)做了序,作為一個(gè)粉絲,還是挺看好這本書(shū)能給我?guī)?lái)一個(gè)新的升華,而且本書(shū)的作者也非常厲害。 使用ES6開(kāi)發(fā)已經(jīng)有1年多了,以前看的是阮一峰老師的ES6教程,也看過(guò)MDN文檔的ES6語(yǔ)法介紹。 最近買(mǎi)了《深入理解ES6》的書(shū)籍來(lái)看,為什么學(xué)習(xí)ES6這么久還要買(mǎi)這本書(shū)呢?主要是看到Daniel A...
閱讀 1780·2021-10-13 09:39
閱讀 1357·2019-08-30 13:58
閱讀 1445·2019-08-29 16:42
閱讀 3592·2019-08-29 15:41
閱讀 3017·2019-08-29 15:11
閱讀 2550·2019-08-29 14:10
閱讀 3440·2019-08-29 13:29
閱讀 2120·2019-08-26 13:27