作爲ES6提供的一種新數據結構,
Set
類似於數組,但其成員卻是唯一的,不會有重複的成員出現.Set
本身是一個構造函數,可以生成Set數據結構
實例化
- 方法1
// 接受數組作爲參數
const arr = [1,2,3]
const s0 = new Set(arr)
console.log(s0) //Set(3) {1, 2, 3}
- 方法2
// html
<span>1</span>
<span>2</span>
<span>3</span>
// 接受類似數組的對象作爲參數
const spans = document.querySelectorAll('span')
console.log(spans)
console.log(new Set(spans)) //Set(3) {span, span, span}
- 方法3
// 實例化後通過add()方法添加元素
const s = new Set()
s.add(1).add(2).add(2).add('2')
console.log(s) //Set(3) {1, 2, "2"}
由此還可以看出來Number
類型的2
和String
類型的 '2'
是不一樣的.Set內部判斷兩個值是否相等的算法類似於 全等運算符( === ) ,最主要的區別在於Set裏面 NaN等於自身, 但是 === 比較中認爲 NaN !== NaN,這個從下面的代碼中可以看出來
s.add(NaN)
console.log(s) //Set(4) {1, 2, "2", NaN}
s.add(NaN)
console.log(s) //Set(4) {1, 2, "2", NaN}
第二次add(NaN)之後再次打印set的數據結構,發現沒有變化,印證了上面的結論
實例方法
操作方法
- add(value)
說明: 添加值,返回Set本身,因此add可以鏈式調用 - delete(value)
說明: 刪除值,返回一個Boolean表示刪除是否成功 - has(value)
說明: 表示是否有這個成員,返回Boolean類型 - clear()
說明: 清除所有成員
add()
const s2 = new Set()
s2.add(1).add(2)
console.log(s2) //Set(2) {1, 2}
delete()
const isSuccess = s2.delete(2)
console.log(isSuccess) //true
console.log(s2) //Set(1) {1}
has()
console.log(s2.has(1)) //true
console.log(s2.has(2)) //false
clear()
s2.clear()
console.log(s2) //Set(0) {}
遍歷方法
- keys()
說明: 返回鍵名 - values()
說明: 返回鍵值 - entries()
說明: 返回鍵值對 - forEach()
說明: 使用回調遍歷每個成員
keys()
const nameArr = ['zhangsan','lisi','wangwu']
const nameSet = new Set(nameArr)
console.log(nameSet.keys()) //SetIterator {"zhangsan", "lisi", "wangwu"}
for(let item of nameSet.keys()){
console.log(item)
}
// zhangsan
// lisi
// wangwu
values()
console.log(nameSet.values()) //SetIterator {"zhangsan", "lisi", "wangwu"}
for(let item of nameSet.values()){
console.log(item)
}
// zhangsan
// lisi
// wangwu
entries()
console.log(nameSet.entries()) //SetIterator {"zhangsan" => "zhangsan", "lisi" => "lisi", "wangwu" => "wangwu"}
for(let item of nameSet.entries()){
console.log(item)
}
// ["zhangsan", "zhangsan"]
// ["lisi", "lisi"]
// ["wangwu", "wangwu"]
for(let item of nameSet){
console.log(item)
}
// zhangsan
// lisi
// wangwu
實例默認就可以被遍歷,默認的就是values()方法
forEach()
nameSet.forEach((v,k) => console.log('key: %s, value: %s',k,v))
// key: zhangsan, value: zhangsan
// key: lisi, value: lisi
// key: wangwu, value: wangwu
Set實現數組去重
- 方法1
const tmpArr = [1,2,2,3]
console.log([...new Set(tmpArr)]) // [1, 2, 3]
- 方法2
const tmpArr = [1,2,2,3]
console.log(Array.from(new Set(tmpArr))) // [1, 2, 3]
WeakSet
WeakSet()的成員只能是對象,而不能是其他的數據類型,這是它與Set()的第一點區別
const wSet = new WeakSet()
console.log(wSet) // WeakSet {}
try{
wSet.add(1)
}catch(e){
console.warn(e) //TypeError: Invalid value used in weak set
}
wSet.add({})
console.log(wSet) //WeakSet {{…}}
第二點區別是WeakSet中對象都是弱引用,垃圾回收機制不考慮WeakSet對該對象的引用,因此WeakSet也是不可遍歷的
const wArr = [3,4]
try{
console.log(new WeakSet(wArr)) //TypeError: Invalid value used in weak set
}catch(e){
console.warn(e)
}
const wArr2 = [[1],[2]]
console.log(new WeakSet(wArr2)) //WeakSet {Array(1), Array(1)}
上面的例子說明數組的成員只能是對象
總結
Set
和 WeakSet
的關係類似於 Map
和 WeakMap
的關係,想要了解 Map
數據結構,可以看另外一篇文章 鏈接: ES6 Map 數據結構