ES6引入了一種新的原始數(shù)據(jù)類型Symbol叛赚,表示讀一無二的值,它是js語言的第七種數(shù)據(jù)類型稽揭,前六種undefined俺附、null、Boolean溪掀、String事镣、Number、Object
Symbol值通過Symbol函數(shù)生成揪胃,這就是說對象的屬性名現(xiàn)在可以有兩種數(shù)據(jù)類型璃哟,一種是原來就有的字符串,另一種就是新增的Symbol類型喊递。凡是屬性名屬于Symbol類型随闪,就都屬于獨(dú)一無二的,這樣保證不會(huì)與其他屬性名產(chǎn)生沖突
Symbol函數(shù)不能使用new命令骚勘,否則會(huì)報(bào)錯(cuò)铐伴。這是因?yàn)樯傻?b>Symbol是一個(gè)原始類型的值,不是對象
Symbol函數(shù)可以接受一個(gè)字符串作為參數(shù)俏讹,表示對Symbol實(shí)例的描述当宴,主要是為了在控制臺(tái)顯示,或者轉(zhuǎn)為字符串泽疆,比較容易區(qū)分
如果Symbol的參數(shù)是一個(gè)對象即供,就會(huì)調(diào)用該對象的toString方法,將其轉(zhuǎn)為字符串于微,然后才生成一個(gè)Symbol值
Symbol函數(shù)的參數(shù)只是表示對當(dāng)前Symbol值得秒搜狐逗嫡,因此相同參數(shù)的Symbol函數(shù)的返回值實(shí)不相等的
Symbol值不能與其他類型的值進(jìn)行運(yùn)算,會(huì)報(bào)錯(cuò)株依,但是可以顯式地轉(zhuǎn)為字符串也可以轉(zhuǎn)為數(shù)值
作為屬性名的Symbol
每一個(gè)Symbol值都是不相等驱证,這意味著Symbol值可以作為標(biāo)識(shí)符恋腕,用于對象的屬性名抹锄,就能保證不會(huì)出現(xiàn)同名的屬性。
不能用點(diǎn)運(yùn)算符
在對象內(nèi)部,使用Symbol值定義屬性時(shí)伙单,Symbol值必須放在方括號之中
魔術(shù)字符串:在代碼多次多次出現(xiàn)获高、與代碼形成強(qiáng)耦合的某一個(gè)具體的字符串或者數(shù)值
屬性名的遍歷
Symbol作為屬性名吻育,該屬性不會(huì)出現(xiàn)在for...in念秧、for...of循環(huán)中。但是布疼,它也不是私有屬性摊趾,有一個(gè)Object.getOwnPropertySymbols方法,可以獲取指定對象所有的Symbol屬性名游两。Object.getOwnPropertySymbols方法返回一個(gè)數(shù)組砾层,成員是當(dāng)前對象的所有用作屬性名的Symbol值
reflect.ownKeys方法返回所有類型的鍵名,包括常規(guī)鍵名和Symbol鍵名
由于Symbol值作為名稱的屬性贱案,不會(huì)被常規(guī)方法遍歷得到肛炮。我們可以利用這個(gè)特性,為對象定義一些非私有的但又希望只用于內(nèi)部的方法
5宝踪、Symbol .for,Symbol.keyFor()
Symbol.for方法可以做到重新使用用一個(gè)Symbol值铸董。
Symbol.for()與Symbol()這兩種寫法,都會(huì)生成新的Symbol肴沫。它們的區(qū)別是粟害,前者會(huì)被登記在全局環(huán)境中供搜索,后者不會(huì)颤芬。Symbol.for()不會(huì)每次調(diào)用就會(huì)返回一個(gè)新的SYmbol類型的值悲幅,而是會(huì)先檢查給定的key是否已經(jīng)存在,如果不存在才會(huì)新建一個(gè)值
Symbol.keyFor方法返回一個(gè)已登記的Symbol類型值的key
6站蝠、實(shí)例:模塊Singleton模式
Singleton模式指的是調(diào)用一個(gè)類汰具,任何時(shí)候返回的都是同一個(gè)實(shí)例
7、內(nèi)置的Symbol值
除了定義自己使用的Symbol值以外菱魔,ES6提供了11個(gè)內(nèi)置的Symbol值留荔,指向語言內(nèi)部使用的方法
1)Symbol.hasInstance屬性,指向一個(gè)內(nèi)部方法澜倦。當(dāng)其他對象使用instanceof運(yùn)算符聚蝶,判斷是否為該對象的實(shí)例時(shí),會(huì)調(diào)用這個(gè)方法
2)Symbol.isConcatSpreadable
對象的Symbol.isConcatSpreadable屬性等于一個(gè)布爾值藻治,表示該對象使用Array.prototype.concat()時(shí)碘勉,是否可以展開
3)Symbol.species
對象的Symbol.species屬性,指向當(dāng)前對象的構(gòu)造函數(shù)桩卵。創(chuàng)造實(shí)例時(shí)验靡,默認(rèn)會(huì)調(diào)用這個(gè)方法,即使用這個(gè)屬性返回的函數(shù)當(dāng)做構(gòu)造函數(shù)來創(chuàng)造新的實(shí)例對象
4)Symbol.match()
指向一個(gè)函數(shù)倍宾,當(dāng)執(zhí)行str.match(myObject)時(shí),如果該屬性存在胜嗓,會(huì)用它高职,返回該方法的返回值
5)Symbol.replace
對象的Symbol.replace屬性,指向一個(gè)方法辞州,當(dāng)該對象被String.prototype.replace方法調(diào)用時(shí)怔锌,會(huì)返回該方法的返回值
6)Symbol.search()
指向一個(gè)方法,當(dāng)該對象被String.prototype.search方法調(diào)用時(shí)孙技,會(huì)返回該方法的返回值
7)Symbol.split
Symbol.split屬性,指向一個(gè)方法排作,當(dāng)該對象被String.prototype.split方法調(diào)用時(shí)牵啦,會(huì)返回該方法的返回值
8)Symbol.iterator
獨(dú)享的Symbol.iterator屬性,指向該對象的默認(rèn)遍歷器方法
9)Symbol.toPrimitive
對象的Symbol.toPrimitive屬性,指向一個(gè)方法.該對象被轉(zhuǎn)為原始類型的值時(shí),會(huì)調(diào)用這個(gè)方法,返回該對象對應(yīng)的原始類型值
10)Symbol.toStringTag
對象的Symbol.toStringTag屬性妄痪,指向一個(gè)方法
11)Symbol.unscopables
對象的Symbol.unscopables哈雏,指向一個(gè)對象。該對象指定了使用with關(guān)鍵字時(shí)衫生,哪些屬性會(huì)被with環(huán)境排除
Set和Map數(shù)據(jù)結(jié)構(gòu)
ES6提供了新的數(shù)據(jù)結(jié)構(gòu)Set裳瘪,它類似于數(shù)組,
但是成員的值都是唯一的罪针,沒有重復(fù)的值
Set本身是一個(gè)構(gòu)造函數(shù)彭羹,用來生成Set數(shù)據(jù)結(jié)構(gòu)
Set函數(shù)可以接受一個(gè)數(shù)組(或類似數(shù)組的對象)作為參數(shù)泪酱,用來初始化派殷。
還可以接受類似數(shù)組的對象作為參數(shù)
向Set加入值得時(shí)候,不會(huì)發(fā)生類型轉(zhuǎn)換墓阀。Set內(nèi)不許判斷兩個(gè)值是否不同,使用的算法叫做“Same-value equality”它類似于與精確相等運(yùn)算符毡惜,主要的區(qū)別是NaN等于自身,而精確相等運(yùn)算符認(rèn)為NaN不等于自身
另外兩個(gè)對象總是不相等的
1)Set實(shí)例的屬性和方法
屬性:
-Set.prototype.constructor:構(gòu)造函數(shù)斯撮,默認(rèn)就是Set函數(shù)
?-Set.prototype.size:返回Set實(shí)例的成員的總數(shù)
方法:(操作方法和遍歷方法)
操作方法:add(value)经伙、delete(value)、has(value)勿锅、clear()
Array.from方法可以將Set結(jié)構(gòu)轉(zhuǎn)為數(shù)組
遍歷方法:
keys()返回鍵名的遍歷器帕膜;values()返回鍵值得遍歷器;entries()返回鍵值對的遍歷器溢十,只有鍵值(鍵名和鍵值是同一個(gè)值泳叠,所以keys方法和values方法的行為完全一致)
forEach()使用回調(diào)函數(shù)遍歷每個(gè)成員。由于Set結(jié)構(gòu)沒有鍵名茶宵,Set結(jié)構(gòu)的實(shí)例的forEach方法危纫,用于對每個(gè)成員執(zhí)行某種操作,沒有返回值。
擴(kuò)展運(yùn)算符和Set結(jié)構(gòu)相結(jié)合种蝶,就可以去除數(shù)組的重復(fù)成員
數(shù)組的map結(jié)構(gòu)和filter方法也可以用于Set
如果想在遍歷操作中契耿,同步改變原來的Set結(jié)構(gòu),目前沒有直接的方法螃征,但又兩種變通方法搪桂。一種是利用原Set結(jié)構(gòu)映射出一個(gè)新的結(jié)構(gòu),然后復(fù)制給原來的Set結(jié)構(gòu)盯滚;另一種是利用Array.from方法
2踢械、WeakSet
WeakSet結(jié)構(gòu)與Set類似,也是不重復(fù)的值得結(jié)合魄藕。但是内列,它與Set有兩個(gè)區(qū)別,首先背率,WeakSet的成員只能是對象话瞧,而不能是其他類型的值
WeakSet中的對象都是弱引用,即垃圾回收機(jī)制不考慮WeakSet對該對象的引用寝姿,也就是說交排,如果如果其他對象都不在引用該對象,那么垃圾回收機(jī)制會(huì)自動(dòng)回收該對象所占用的內(nèi)存饵筑,不考慮該對象還存在與WeakSet之中
語法:
const ws = new WeakSet()埃篓。WeakSet是一個(gè)勾走函數(shù),可以使用new命令根资,創(chuàng)建WeakSet數(shù)據(jù)結(jié)構(gòu)
WeakSet可以接受一個(gè)數(shù)組或類似數(shù)組的對象作為參數(shù)都许。
WeakSet不能遍歷,是因?yàn)槌蓡T都是弱引用
3嫂冻、Map
鍵值對的鍵只接受鍵作為鍵名胶征,ES6提供了Map數(shù)據(jù)結(jié)構(gòu),Object結(jié)構(gòu)提供了“字符串--值”的對應(yīng)桨仿,Map結(jié)構(gòu)提供了“值--值”的對應(yīng)睛低。
Map構(gòu)造函數(shù)接受數(shù)組作為參數(shù),不僅僅是數(shù)組服傍,任何具有Iterator接口的數(shù)據(jù)結(jié)構(gòu)都可以當(dāng)做Map構(gòu)造函數(shù)的參數(shù)钱雷,這就是說Set和Map都可以用來生成新的Map。
實(shí)例的屬性和操作方法
屬性:size屬性吹零;set(key罩抗,value)set方法設(shè)置鍵名key隊(duì)形的鍵值為value,然后返回整個(gè)Map結(jié)構(gòu)灿椅。如果key已經(jīng)有值套蒂,則鍵值會(huì)被更新钞支,否則就生成該鍵
set方法返回的是當(dāng)前的Map對象,因此可以采用鏈?zhǔn)綄懛?/p>
get(key)方法讀取key對應(yīng)的鍵值操刀,如果找不到key烁挟,返回undefined
has方法返回一個(gè)布爾值,表示某個(gè)值是否在當(dāng)前Map對象之中骨坑。
delete(key)delete方法刪除某個(gè)鍵撼嗓,返回true。如果刪除失敗欢唾,返回false
clear方法清除所有成員且警,沒有返回值
遍歷方法:
Map結(jié)構(gòu)原生提供三個(gè)遍歷器和生成函數(shù)和一個(gè)遍歷方法
-keys()返回鍵名的遍歷器;values()返回鍵值得遍歷器礁遣;-entries()返回所有成員的遍歷器斑芜;forEach()遍歷Map的所有成員
上面代碼最后的那個(gè)例子,表示Map結(jié)構(gòu)的默認(rèn)遍歷器接口亡脸,就是entries方法
Map結(jié)構(gòu)轉(zhuǎn)為數(shù)組結(jié)構(gòu)押搪,比較快速的方法是使用擴(kuò)展運(yùn)算符
與其他數(shù)據(jù)結(jié)構(gòu)的互相轉(zhuǎn)換
1)Map轉(zhuǎn)為數(shù)組(使用擴(kuò)展運(yùn)算符...)
2)數(shù)組轉(zhuǎn)為Map
將數(shù)組傳入Map構(gòu)造函數(shù)树酪,就可以轉(zhuǎn)為Map
new Map([
[true,7],
[{foo:3},['abc']]
])
3)Map轉(zhuǎn)為對象浅碾,如果所有Map的鍵都是字符串,它可以轉(zhuǎn)為對象续语。
4)對象轉(zhuǎn)為Map
5)Map轉(zhuǎn)為JSON垂谢,分為兩種情況,一種情況是疮茄,Map的鍵名都是字符串滥朱,這是可以選擇為對象JSON
另一種情況是,Map的鍵名有非字符串力试,這是可以算則轉(zhuǎn)為數(shù)組JSON
6)JSON轉(zhuǎn)為Map
4徙邻、WeakMap
Weak結(jié)構(gòu)與Map結(jié)構(gòu)類似,也是用于生成鍵值對的結(jié)合
WeakMap與Map的區(qū)別
WeakMap只接受對象作為鍵名(null除外)畸裳,不接受其他類型的值作為鍵名