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方法。