ES6學習筆記篇二之Set/Map集合和數組的擴展

一、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、WeakMapsize、forEach、clear 方法都不存在

const wm = new WeakMap();
wm.size // undefined
wm.forEach // undefined
wm.clear // undefined
  1. 它的鍵存儲的地址不會影響垃圾回收
  2. 它的鍵只能是對象
  3. 不能遍歷(不是可迭代的對象)、沒有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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章