前言
初衷: 最近在讀《深入理解Es6》這本書(shū),之前沒(méi)好好全面學(xué)過(guò)Es6語(yǔ)法则果,也是趁著不忙的階段重新好好研究一下整理一下筆記分享給大家幔翰,不喜勿噴。
適合人群:前端初級(jí)開(kāi)發(fā)西壮,大佬繞道遗增。
內(nèi)容結(jié)構(gòu):概念 -> 基本語(yǔ)法 -> 應(yīng)用場(chǎng)景
在Es6之前,數(shù)組一直是JavaScript
中唯一的集合類(lèi)型款青,不過(guò)有一些開(kāi)發(fā)者們認(rèn)為非數(shù)組對(duì)象的也是集合做修,只不過(guò)是鍵值對(duì)集合。但是在Es6之前抡草,開(kāi)發(fā)者們只能使用數(shù)組集合饰及,但是數(shù)組是用下標(biāo)索引index
取值,所以經(jīng)常被用于創(chuàng)建隊(duì)列和棧康震,如果開(kāi)發(fā)者們要使用非數(shù)組索引集合燎含,就會(huì)使用對(duì)象字面量場(chǎng)景所需的結(jié)構(gòu)。
Set是什么
Set是一個(gè)無(wú)重復(fù)元素的集合腿短,但不會(huì)像數(shù)組那樣用索引值去訪(fǎng)問(wèn)數(shù)組值屏箍,通常的做法是檢測(cè)某個(gè)值是否存在這個(gè)集合中。
為什么要出Set
我們來(lái)看兩個(gè)案例講解一下為什么要出Set
案例一
let o = {}
let key1 = {}
let key2 = {}
o[key1] = "val"
console.log(o[key1]) // val
console.log(o[key2]) // val
上面example中橘忱, 對(duì)象的鍵值都會(huì)轉(zhuǎn)換為字符串[object Object]
,內(nèi)部都會(huì)調(diào)用toString
赴魁,所以不管使用key1
還是key2
都會(huì)返回相同的val
值。
案例二
let o = {}
o.count = 1;
if (o.count) {
console.log(o.count)
}
上面example中钝诚,存在兩個(gè)問(wèn)題是到底是判斷有沒(méi)有這個(gè)屬性呢颖御,還是檢測(cè)值是否非零,如果對(duì)象這個(gè)值真的等于0那么這個(gè)判斷就不會(huì)執(zhí)行凝颇,如果出現(xiàn)在大型項(xiàng)目中這種問(wèn)題不容易被發(fā)現(xiàn)潘拱。(有的小伙伴可能認(rèn)為秉继,檢測(cè)對(duì)象有沒(méi)有這個(gè)屬性誰(shuí)這樣寫(xiě)啊,可以使用in
操作符或者getOwnProperty
)希望這里不要跟我杠霸箢酢尚辑!,盡管可以使用盔腔,但要明白本文這里講的是Set
那么我們來(lái)說(shuō)說(shuō)Set
杠茬,Set
集合是一個(gè)有序列表,里面不會(huì)出現(xiàn)重復(fù)的值弛随,唯一例外的是在Set
中+0
和-0
是相等的瓢喉。Set
中也不會(huì)對(duì)所存儲(chǔ)的值進(jìn)行轉(zhuǎn)換,如上面的{}
直接轉(zhuǎn)換為[object Object]
在Set
中不會(huì)存在這種情況舀透,當(dāng)然也包括數(shù)值類(lèi)型和字符串類(lèi)型24
和"24"
這兩種也不會(huì)存在沖突栓票。
let o = new Set()
let key1 = {}
let key2 = {}
o.add(key1)
o.add(key2)
console.log(o.size) // 2
上面example中,可以看到添加了2個(gè)對(duì)象{}
愕够,size
是有2條數(shù)據(jù)也就是并沒(méi)有被覆蓋走贪。下面我們來(lái)認(rèn)識(shí)一下它們的語(yǔ)法吧
基礎(chǔ)語(yǔ)法
Set
是一個(gè)構(gòu)造函數(shù),它參數(shù)接收所有可迭代對(duì)象(Iterator)惑芭,數(shù)組坠狡、字符串、Set集合等這些都是可迭代的遂跟。
添加元素
調(diào)用new Set()
創(chuàng)建Set
集合逃沿,使用add
方法給集合里添加對(duì)象。
let o = new Set()
o.add(24)
o.add("24")
console.log(o.size) // 查看集合的元素?cái)?shù)量 2
上面這個(gè)example幻锁,可以清楚的看到Set
集合中是沒(méi)有將鍵值強(qiáng)制轉(zhuǎn)換為字符串的凯亮,不同類(lèi)型和指針都會(huì)彼此獨(dú)立。
上面我們也說(shuō)了Set
集合中不會(huì)重新重復(fù)值
let o = new Set()
o.add(24)
o.add(24) // 這一行代碼則會(huì)忽略哄尔,
let arr = new Set([1,1,2,3,4,5,1])
上面example中假消,第二次跟第一個(gè)傳入的值并且類(lèi)型都一樣,所以Set
則會(huì)忽略該代碼不會(huì)添加到集合中究飞≈们看下方那個(gè)arr
變量聲明直接初始化了一些數(shù)組值,而這些里面數(shù)值重復(fù)的會(huì)直接過(guò)濾掉亿傅,在生成的時(shí)候會(huì)只有一個(gè)。
檢測(cè)元素
調(diào)用has
方法來(lái)檢測(cè)集合中是否存在某個(gè)值瘟栖,返回值為Boolean
值葵擎,集合不能像數(shù)組那樣獲取索引值,在Set
集合中是沒(méi)有index
索引值的半哟。
let o = new Set()
o.add("蛙人")
console.log(o.has("蛙人")) // true
移除元素
調(diào)用delete
方法可以移除Set
集合中某一個(gè)元素酬滤,返回值返回Boolean
签餐,也可以調(diào)用clear
方法將集合中元素全部移除,clear
方法沒(méi)有返回值盯串。
單個(gè)移除
let o = new Set()
o.add("蛙人")
o.delete("蛙人") // true
console.log(o.size) 0
全部移除
let o = new Set()
o.add("蛙人")
o.clear()
console.log(o.size) 0
Set集合使用forEach遍歷
這里Set
的forEach遍歷和數(shù)組的forEach遍歷使用方法一模一樣氯檐,就是參數(shù)返回值有些不同。該Set
方法的forEach也接收三個(gè)參數(shù)体捏。
- Set集合里索引位置
- 與第一個(gè)參數(shù)一樣的值
- Set集合本身
let o = new Set(["蛙人", 24, "male"])
o.forEach((value, key, self) => {
console.log(value, key, self)
// 蛙人 蛙人 set對(duì)象
// 24 24 set對(duì)象
// male male set對(duì)象
})
上面exmaple中冠摄,只所以forEach第一個(gè)參數(shù)和第二個(gè)參數(shù)一樣的原因是因?yàn)椋?code>Set對(duì)象中本沒(méi)有索引值,所以它的索引值參數(shù)也是值几缭,Es6官方本可以去掉這個(gè)參數(shù)的河泳,但是考慮到怕開(kāi)發(fā)者誤會(huì)和傳統(tǒng)的forEach不一樣,所以就統(tǒng)一了參數(shù)年栓。
應(yīng)用場(chǎng)景
去重
let list = [1,3,1,2,3,5]
let o = new Set(list);
console.log(o) // 1 3 2 5
let newList = [...o] // 將遍歷對(duì)象集合轉(zhuǎn)換為真數(shù)組
上面example中拆挥,我們大部分場(chǎng)景下使用該方法都是去重,然后去重完在轉(zhuǎn)換為真數(shù)組某抓。
感謝
謝謝各位在百忙之中點(diǎn)開(kāi)這篇文章纸兔,希望對(duì)你們能有所幫助,如有問(wèn)題歡迎各位大佬指正否副。
如果覺(jué)得寫(xiě)得還行的話(huà)食拜,那就點(diǎn)個(gè)贊吧。
感興趣的小伙伴可以加入 前端娛樂(lè)圈交流群 歡迎大家一起來(lái)交流討論