一、set 集合
Set:它類似於數組,但是成員的值都是唯一的,沒有重複的值。set用於存放不重複的數據
1、創建Set 集合
new Set(); //創建一個沒有任何內容的set集合
new Set(iterable); //創建一個具有初始內容的set集合,內容來自於可迭代對象每一次迭代的結果
const arr = [1,2,3,4,5,1,2]
const sets = new Set(arr)
console.log(sets)
2、Set 集合的增刪改查
(1)add(data):添加一個數據到set集合末尾,如果數據已存在,則不進行任何操作
(2)has(data): 判斷set中是否存在對應的數據
(3)delete(data):刪除匹配的數據,返回是否刪除成功
(4)clear():清空整個set集合
(4)size:獲取set集合中的元素數量,只讀屬性,無法重新賦值
const arr = [1,2,3,4,5,2]
//const sets = new Set([1,2,3,4,5,2])
const sets = new Set(arr)
sets.add(7) //Set(6) {1, 2, 3, 4, 5, 7}
sets.delete(2) //Set(5) {1, 3, 4, 5, 7}
const res = sets.has(2)//false
sets.size //5
sets.clear() //Set(0){}
注意:Set 使用Object.is()的方式判斷兩個數據是否相同,但是,針對+0和-0,set認爲是相等
3、與數組字符串進行相互轉換
const s = new Set([x,x,x,x,x]);
// set本身也是一個可迭代對象,每次迭代的結果就是每一項的值
const arr = [...s];
數組去重:
let arr = [1,2,3,4,5,1,2]
arr = [...new Set(arr)]
console.log(arr)
字符串去重:
let str = "aslfhjiowvmlkpwifgefjmsa"
str = [...new Set(str)].join("")
console.log(str)
4、Set 遍歷
(1)使用for-of循環
const sets = new Set([1,5,2,4,3,2])
for (const item of sets) {
console.log(item) //1
}
(2)使用set中的實例方法forEach
const sets = new Set([1,5,2,4,3,2])
sets.forEach((ele,index,s) => {
//set集合中沒有下標,因此ele和index是一樣的
console.log(ele,index,s) //1 1 Set(5) {1, 5, 2, 4, 3}
});
注意:set集合中不存在下標,因此forEach中的回調的第二個參數和第一個參數是一致的,均表示set中的每一項
求兩個數組的並集,交集,差集
const arr1 = [1,4,7,9,6,0]
const arr2 = [4,5,6,1,3,2]
//並集
const result1 = [...new Set(arr1.concat(arr2))]
const result2 = [...new Set([...arr1,...arr2])]
console.log("並集",result1,result2)
//交集
let s1 = new Set(arr1)
let s2 = new Set(arr2)
const result3 = [...s1].filter(item=>{
return s2.has(item)
})
console.log("交集",result3)
//差集
const result4 = [...new Set([...arr1,...arr2])].filter(item=>result3.indexOf(item)<0)
console.log("差集",result4)
5、手寫Set (仿照,並非真實底層實現)
//手寫set
class MySet{
constructor(iterator = []){
//驗證是否可迭代對象 Symbol.iterator知名符號
if(typeof iterator[Symbol.iterator] !== "function"){
throw new TypeError("你提供的不是可迭代的對象")
}
this._datas = []; //存放set數據
for (const item of iterator) {
this.add(item)
}
}
//set的添加方法
add(data){
if(!this.has(data))
this._datas.push(data)
}
//判斷是否含有一個元素。
has(data){
for (const item of this._datas) {
if(this.isEqual(item,data)){
return true
}
}
return false
}
//判斷兩個元素是否相等,用Object.is()方法判斷。特殊判斷,+0和-0的情況
isEqual(data1,data2){
if(data1 === 0 && data2 === 0){
return true
}
return Object.is(data1,data2)
}
//刪除元素
delete(data){
for(let i=0;i<this._datas.length;i++){
const ele = this._datas[i]
if(this.isEqual(ele,data)){ //找到元素
this._datas.splice(i,1) //刪除元素
return true
}
}
return false
}
//清除元素的方法
clear(){
this._datas = []
}
*[Symbol.iterator](){
for(const item of this._datas){
yield item //迭代器中的關鍵字
}
}
//提供forEach方法迭代遍歷
forEach(callback){
for (const item of this._datas) {
callback(item,item,this)
}
}
}
let s = new MySet([1,2,2,3,4,5])
console.log(s)
s.forEach((item,index,data)=>{
console.log(item,index,data)
})
二、WeakSet
WeakSet 集合與 Set 類似,也是不重複的值的集合
1、WeakSet 的成員只能是對象,而不能是其他類型的值。
const ws = new WeakSet();
ws.add(1)
// TypeError: Invalid value used in weak set
2、WeakSet 中的對象都是弱引用
垃圾回收機制不考慮 WeakSet 對該對象的引用,也就是說,如果其他對象都不再引用該對象,那麼垃圾回收機制會自動回收該對象所佔用的內存,不考慮該對象還存在於 WeakSet 之中。
3、不能遍歷(不是可迭代的對象)、沒有size屬性、沒有forEach方法
三、Map集合
它類似於對象,也是鍵值對的集合,但是“鍵”的範圍不限於字符串,各種類型的值(包括對象)都可以當作鍵。
鍵值對(key value pair)數據集合的特點:鍵不可重複.也就是說,Object 結構提供了“字符串—值”的對應,Map 結構提供了“值—值”的對應,是一種更完善的 Hash 結構實現。如果你需要“鍵值對”的數據結構,Map 比 Object 更合適。
map集合專門用於存儲多個鍵值對數據。
1、創建Map
new Map(); //創建一個空的map
new Map(iterable); //創建一個具有初始內容的map,初始內容來自於可迭代對象每一次迭代的結果,但是,它要求每一次迭代的結果必須是一個長度爲2的數組,數組第一項表示鍵,數組的第二項表示值
2、Map的增刪改查
(1)size:只讀屬性,獲取當前map中鍵的數量
(2)set(鍵, 值):設置一個鍵值對,鍵和值可以是任何類型
- 如果鍵不存在,則添加一項
- 如果鍵已存在,則修改它的值
- 比較鍵的方式和set相同
(3)get(鍵): 根據一個鍵得到對應的值
(4)has(鍵):判斷某個鍵是否存在
(5)delete(鍵):刪除指定的鍵
(6)clear():清空map
const map1 = new Map([["a",1],["b",2]])
map1.set({a:1},1) //0: {"a" => 1}
//1: {"b" => 2}
//2: {Object => 1}
//>key: {a: 1}
//>value: 1
console.log(map1.get("a")) //1
map1.delete("a")
console.log(map1.has("a")) //false
console.log(map1.size) //2
3、與數組互相轉換
let arr = [[1,2],[3,4],[5,1]]
arr = [...new Map(arr)]
console.log(arr)
4、遍歷
(1)for-of,每次迭代得到的是一個長度爲2的數組
const map1 = new Map([["a",1],["b",2]])
for (const [key,value] of map1) {
console.log(key,value)
}
(2)forEach,通過回調函數遍歷
const map1 = new Map([["a",1],["b",2]])
/*
參數1:每一項的值
參數2:每一項的鍵
參數3:map本身
*/
map1.forEach((key,value,m) => {
console.log(key,value,m)
});
5、手寫Map
class MyMap{
constructor(iterator = []){
if(typeof iterator[Symbol.iterator] !== "function"){
throw new TypeError("Uncaught TypeError")
}
this._datas = []
for (const item of iterator) {
if(typeof item[Symbol.iterator] !== "function"){
throw new TypeError("Uncaught TypeErro")
}
const it = item[Symbol.iterator]()
const key = it.next().value
const value = it.next().value
this.set(key,value)
}
}
//設置key-value
set(key,value){
const obj = this._getObj(key)
if(obj){
obj.value = value
}else{
this._datas.push({key,value})
}
}
//獲取value值
get(key){
const item = this._getObj(key)
if(item){
return item.key
}
return undefined
}
_getObj(key){
//根據key值,找到對想
for (const item of this._datas) {
if(this.isEqual(key,item.key)){
return item
}
}
return undefined
}
delete(key){
for(let i=0;i<this._datas.length;i++){
if(this.isEqual(key,this._datas[i].key)){
this._datas.splice(i,1)
return true
}
}
}
has(key){
return _getObj(key) !== undefined
}
isEqual(data1,data2){
if(data1 === 0 && data2 === 0){
return true
}
return Object.is(data1,data2)
}
}
const mymap = new MyMap([["a",1],["b",2]]);
mymap.set(1,2)
mymap.delete("a")
console.log(mymap)
四、WeakMap
1、WeakMap
只接受對象作爲鍵名(null
除外),不接受其他類型的值作爲鍵名。
const map = new WeakMap();
map.set(1, 2)// TypeError: 1 is not an object!
2、WeakMap
的鍵名所指向的對象,不計入垃圾回收機制。
3、WeakMap
size、forEach、clear 方法都不存在
const wm = new WeakMap();
wm.size // undefined
wm.forEach // undefined
wm.clear // undefined
- 它的鍵存儲的地址不會影響垃圾回收
- 它的鍵只能是對象
- 不能遍歷(不是可迭代的對象)、沒有size屬性、沒有forEach方法
五、數組的擴展
1、靜態方法
(1)Array.of(…args):使用指定的數組項創建一個新數組
const arr = Aarray.of(1,2,3,4,5)
//解決
const arr1 = new Array(1)//表示的是數組長度
(2)Array.from(arg):通過給定的類數組 或 可迭代對象 將它轉爲真正的數組。
const divs = document.querySelectorAll("div")
//Array.prototype.slice.call(divs,0)
const divArr = Array.from(divs)
2、實例方法
(1)find(callback):用於查找滿足條件的第一個元素
const arr = [
{id:1,name:"llx"},
{id:2,name:"lkh"},
{id:3,name:"qqw"}
]
const result = arr.find(item=>item.id === 2)
console.log(result) //{id: 2, name: "lkh"}
(2)findIndex(callback):用於查找滿足條件的第一個元素的下標
const arr = [1, 5, 10, 15]
const result = arr.findIndex((value, index, arr) => {
return value > 9;
})
console.log(result)// 2
(3)fill(data):用指定的數據填充滿數組所有的內容
const arr = new Array(10)//表示的是數組長度
arr.fill(0)
console.log(arr) //[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
(4)copyWithin(target, start, end):在數組內部完成複製
const arr = [1,2,3,4,5,6]
arr.copyWithin(2) //[1, 2, 1, 2, 3, 4]
const arr = [1,2,3,4,5,6]
arr.copyWithin(2,1)// [1, 2, 2, 3, 4, 5]
const arr = [1,2,3,4,5,6]
arr.copyWithin(2,1,3) //[1, 2, 2, 3, 5, 6]
(5)includes(data):判斷數組中是否包含某個值,使用Object.is匹配
const arr = [1,2,3,4]
arr.includes(2) //true