JavaScript面試考點(diǎn)之set、weakSet、map及weakMap 的詳解

Set 和 Map 主要的應(yīng)用場(chǎng)景在于數(shù)據(jù)重組數(shù)據(jù)儲(chǔ)存。Set 是一種叫做集合的數(shù)據(jù)結(jié)構(gòu),Map 是一種叫做字典的數(shù)據(jù)結(jié)構(gòu)。

1、Set

ES6 新增的一種新的數(shù)據(jù)結(jié)構(gòu),類似于數(shù)組,但成員是唯一且無序的,沒有重復(fù)的值。Set 本身是一種構(gòu)造函數(shù),用來生成 Set 數(shù)據(jù)結(jié)構(gòu)。

特點(diǎn):1)成員唯一,無序不重復(fù)。

2)[value,value],鍵值與鍵名一致,也可以說只有鍵值,沒有鍵名。

3)可以遍歷,方法有:add、delete、has。

向 Set 加入值的時(shí)候,不會(huì)發(fā)生類型轉(zhuǎn)換,所以5和"5"是兩個(gè)不同的值。Set 內(nèi)部判斷兩個(gè)值是否不同,使用的算法叫做“Same-value-zero equality”,它類似于精確相等運(yùn)算符(===),主要的區(qū)別是,Set 認(rèn)為NaN等于自身,而精確相等運(yùn)算符認(rèn)為NaN不等于自身。

4)Set 實(shí)例屬性

constructor 構(gòu)造函數(shù);size 元素?cái)?shù)量。

5)Set 實(shí)例方法:

add(value):新增,相當(dāng)于 array里的push。

delete(value):存在即刪除集合中value。

has(value):判斷集合中是否存在 value。

clear():清空集合。

Array.from方法可以將 Set 結(jié)構(gòu)轉(zhuǎn)為數(shù)組。

6)遍歷方法(遍歷順序?yàn)椴迦腠樞颍?/b>

keys():返回一個(gè)包含集合中所有鍵的迭代器

values():返回一個(gè)包含集合中所有值得迭代器

entries():返回一個(gè)包含Set對(duì)象中所有元素得鍵值對(duì)迭代器

forEach(callbackFn, thisArg):用于對(duì)集合成員執(zhí)行callbackFn操作,如果提供了 thisArg 參數(shù),回調(diào)中的this會(huì)是這個(gè)參數(shù),沒有返回值。

Set 可默認(rèn)遍歷,默認(rèn)迭代器生成函數(shù)是 values() 方法。

7)Set可以使用 map、filter 方法

8)Set實(shí)現(xiàn)交集(Intersect)、并集(Union)、差集(Difference)。

2、WeakSet

WeakSet 對(duì)象允許你將弱引用對(duì)象儲(chǔ)存在一個(gè)集合中。

特點(diǎn):1)成員都是對(duì)象。WeakSet 只能儲(chǔ)存對(duì)象引用,不能存放值,而 Set 對(duì)象都可以。

2)成員都是弱引用,可以被垃圾回收機(jī)制回收,可以用來保存DOM節(jié)點(diǎn),不容易造成內(nèi)存泄漏。WeakSet 對(duì)象中儲(chǔ)存的對(duì)象值都是被弱引用的,即垃圾回收機(jī)制不考慮 WeakSet 對(duì)該對(duì)象的應(yīng)用,如果沒有其他的變量或?qū)傩砸眠@個(gè)對(duì)象值,則這個(gè)對(duì)象將會(huì)被垃圾回收掉(不考慮該對(duì)象還存在于 WeakSet 中),所以,WeakSet 對(duì)象里有多少個(gè)成員元素,取決于垃圾回收機(jī)制有沒有運(yùn)行,運(yùn)行前后成員個(gè)數(shù)可能不一致,遍歷結(jié)束之后,有的成員可能取不到了(被垃圾回收了),WeakSet 對(duì)象是無法被遍歷的(ES6 規(guī)定 WeakSet 不可遍歷),也沒有辦法拿到它包含的所有元素。

3)不可以遍歷,方法有:add、delete、has。

4)Set 實(shí)例方法

add(value):在WeakSet 對(duì)象中添加一個(gè)元素value。

has(value):判斷 WeakSet 對(duì)象中是否包含value。

delete(value):刪除元素 value。

clear():清空所有元素,注意該方法已廢棄。

3、Map

1)本質(zhì)上是鍵值對(duì)的集合。

2)可以遍歷,方法很多,可以跟各種數(shù)據(jù)格式轉(zhuǎn)換。

3)任何具有 Iterator 接口、且每個(gè)成員都是一個(gè)雙元素的數(shù)組的數(shù)據(jù)結(jié)構(gòu)都可以當(dāng)作Map構(gòu)造函數(shù)的參數(shù)。

4)如果讀取一個(gè)未知的鍵,則返回undefined。只有對(duì)同一個(gè)對(duì)象的引用,Map 結(jié)構(gòu)才將其視為同一個(gè)鍵。

上面代碼的set和get方法,表面是針對(duì)同一個(gè)鍵,但實(shí)際上這是兩個(gè)值,內(nèi)存地址是不一樣的,因此get方法無法讀取該鍵,返回undefined。

Map 的鍵實(shí)際上是跟內(nèi)存地址綁定的,只要內(nèi)存地址不一樣,就視為兩個(gè)鍵。

如果 Map 的鍵是一個(gè)簡(jiǎn)單類型的值(數(shù)字、字符串、布爾值),則只要兩個(gè)值嚴(yán)格相等,Map 將其視為一個(gè)鍵,比如0和-0就是一個(gè)鍵,布爾值true和字符串true則是兩個(gè)不同的鍵。另外,undefined和null也是兩個(gè)不同的鍵。雖然NaN不嚴(yán)格相等于自身,但 Map 將其視為同一個(gè)鍵。

4)操作方法:

set(key, value):向字典中添加新元素。

get(key):通過鍵查找特定的數(shù)值并返回。

has(key):判斷字典中是否存在鍵key。

delete(key):通過鍵 key 從字典中移除對(duì)應(yīng)的數(shù)據(jù)。

clear():將這個(gè)字典中的所有元素刪除。

5)遍歷方法

Keys():將字典中包含的所有鍵名以迭代器形式返回。

values():將字典中包含的所有數(shù)值以迭代器形式返回。

entries():返回所有成員的迭代器。forEach():遍歷字典的所有成員。

Map 結(jié)構(gòu)的默認(rèn)遍歷器接口(Symbol.iterator屬性),就是entries方法。

6)與其他數(shù)據(jù)結(jié)構(gòu)的相互轉(zhuǎn)換

a、Map 結(jié)構(gòu)轉(zhuǎn)為數(shù)組結(jié)構(gòu),比較快速的方法是使用擴(kuò)展運(yùn)算符(...)。

Array 轉(zhuǎn) Map

b、Map 轉(zhuǎn) Object

因?yàn)?Object 的鍵名都為字符串,而Map 的鍵名為對(duì)象,所以轉(zhuǎn)換的時(shí)候會(huì)把非字符串鍵名轉(zhuǎn)換為字符串鍵名。

Object 轉(zhuǎn) Map

c、Map 轉(zhuǎn) JSON

JSON 轉(zhuǎn) Map

JS 中的對(duì)象(Object),本質(zhì)上是鍵值對(duì)的集合(hash 結(jié)構(gòu))。

但當(dāng)以一個(gè)DOM節(jié)點(diǎn)作為對(duì)象 data 的鍵,對(duì)象會(huì)被自動(dòng)轉(zhuǎn)化為字符串[Object HTMLCollection],所以說,Object 結(jié)構(gòu)提供了字符串-值對(duì)應(yīng),Map則提供了值-值的對(duì)應(yīng)。

4、WeakMap

WeakMap 對(duì)象是一組鍵值對(duì)的集合,其中的鍵是弱引用對(duì)象,而值可以是任意。WeakMap 弱引用的只是鍵名,而不是鍵值。鍵值依然是正常引用。

WeakMap 中,每個(gè)鍵對(duì)自己所引用對(duì)象的引用都是弱引用,在沒有其他引用和該鍵引用同一對(duì)象,這個(gè)對(duì)象將會(huì)被垃圾回收(相應(yīng)的key則變成無效的),所以,WeakMap 的 key 是不可枚舉的。

1)只接受對(duì)象作為鍵名(null除外),不接受其他類型的值作為鍵名。

2)鍵名是弱引用,鍵值可以是任意的,鍵名所指向的對(duì)象可以被垃圾回收,此時(shí)鍵名是無效的。

3)不能遍歷,方法有g(shù)et、set、has、delete。

4)操作方法:

has(key):判斷是否有 key 關(guān)聯(lián)對(duì)象。

get(key):返回key關(guān)聯(lián)對(duì)象(沒有則則返回 undefined)。

set(key):設(shè)置一組key關(guān)聯(lián)對(duì)象。

delete(key):移除 key 的關(guān)聯(lián)對(duì)象。

5、對(duì)比

1)WeakSet和WeakMap

WeakSet的成員只能是對(duì)象,WeakMap只接受對(duì)象(null除外)作為鍵名;

WeakSet和WeakMap沒有遍歷操作,沒有size屬性,沒有clear方法;

因?yàn)閃eakSet中的對(duì)象是弱引用,WeakMap的鍵名所引用的對(duì)象也是弱引用。

WeakSet中的對(duì)象不計(jì)入垃圾回收機(jī)制,WeakMap中鍵名指向的對(duì)象不計(jì)入垃圾回收機(jī)制。垃圾回收機(jī)制不將它們的引用考慮在內(nèi)。一旦不再需要,垃圾回收機(jī)制會(huì)自動(dòng)將它們回收,不用手動(dòng)刪除,避免了內(nèi)存的泄露。因?yàn)閃eakSet的成員和WeakMap引用的鍵名可能會(huì)隨時(shí)消失,所以WeakSet和WeakMap沒有遍歷操作,也沒有size屬性,并且兩者都沒有clear方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容