1. 程式人生 > >ES6 Set和Map

ES6 Set和Map

Set

  • Set集合是一種無重複元素的列表,通常的用途用以檢測給定的元素在某個集合中是否存在

  • ES5模擬Set

        var set = Object.create(null);
    
        set.foo = true;
    
        if (set.foo) {}
        if ('foo' in set) {}
    
  • ES6裡面的Set

    • Set型別是一種有序列表,不會對鍵進行強制型別轉換(物件的鍵只能是字串,故會對鍵進行強制型別轉換)

    • 初始化

          let set = new Set(); // 無引數
          let set = new Set([1, 2, 3, 4]); // 引數為陣列,會對陣列去重,鍵為元素
      let set = new Set(iterableObj); // 任何可迭代物件,包括Set和Map
    • Set使用Object.is()比較兩個鍵是否相同,注意:鍵+0和-0會被認為是同一個鍵,但Object.is(+0, -0) = false

    • 增刪查

          let set = new Set();
      
          set.add(1);
          set.add(2);
          set.add(3);
          set.add(4);
          console.log(set.size); // 4,返回集合的長度
          console.log(set.has(1)); // true
          set
      .delete(1); console.log(set.has(1)); // false set.clear(); // 清空 console.log(set.size); // 0
    • 遍歷方法forEach

      • 引數

        Set集合中下一次索引的位置

        與第一個引數一樣的值(主要是為了跟Map、陣列一樣接受三個引數)

        集合本身

          let set = new Set(['a', 'b']);
      
          set.forEach((value, key, ownerSet) => {
              console.log(value, key, ownerSet ===
      set); }); // 'a', 'a', true // 'b', 'b', true
    • 不能通過索引來直接訪問元素

    • 使用展開運算子…即可將set轉換為陣列

          let set = new Set(['a', 'b']);
      
          console.log([...set]); // ['a', 'b']
      

Weak Set

  • Weak Set集合只儲存物件的弱引用,並且不可以儲存原始值;集合中的弱引用如果是物件唯一的引用,則會被回收並釋放相應的記憶體

  • 增刪查(除此之外沒有其他的方法,無清空方法clear)

        let set = new WeakSet(),
            key = {};
        
        set.add(key);
    
        console.log(set.has(key));    // true
    
        set.delete(key);
    
        console.log(set.has(key));    // false
    
  • Weak Set建構函式不接受任何原始值,如果數組裡麵包含其他非物件值,程式會丟擲錯誤

        let key1 = {}, key2 = {};
        let set = new WeakSet([key1, key2]);
    
  • 在WeakSet例項中,如果向add()方法傳入非物件引數會導致程式報錯,而向has()和delete()方法傳入非物件引數則會返回false

  • WeakSet集合不可迭代,所以不能被用於for-of迴圈

  • WeakSet集合不暴露任何迭代器(例如keys()和value()方法),所以無法通過程式本身來檢查其中的內容

  • WeakSet集合不支援forEach()方法

  • WeakSet集合不支援size屬性

  • 如果只需要跟蹤物件引用,更應該使用WeakSet集合而不是普通的Set集合

Map

  • Map型別是一種儲存著許多鍵值對的有序列表,其中的鍵名和對應的值支援所有的資料型別

  • 增刪查改

        let map = new Map();
        map.set('name', 'Crane'); // 增加和修改都是同一個介面
        map.set('age', 22);
        map.set('gf', 0);
    
        console.log(map.has('name')); // 查詢
    
        console.log(map.get('name')); // 獲取
        console.log(map.get('age')); // 獲取
    
        console.log(map.size); // 獲取長度
        map.delete('gf'); // 刪除一個鍵值對
        console.log(map.size);
        map.clear(); // 清空map
        console.log(map.size);
    
  • 例項化

        // 使用陣列傳參:
        // 確保鍵值對被儲存到Map集合中之前不會被強制轉換為其他資料型別
        let map = new Map([['name', 'Crane'], ['age', 22]]);
    
  • 遍歷方法forEach

    • 引數:

      Map集合中下一次索引的位置

      值對應的鍵名

      Map集合本身

        let map = new Map([['name', 'Crane'], ['age', 22]]);
    
        map.forEach((value, key, ownerMap) => {
            console.log(key + ' ' + value);
            console.log(ownerMap === map);
        });
    
        // name Crane
        // true
        // age 25
        // true
    

WeakMap

  • WeakMap集合中的鍵名必須是一個物件,如果使用非物件鍵名會報錯,集合中儲存的是這些值的弱引用,如果在弱引用之外不存在其他的強引用,引擎的垃圾回收機制會自動回收這個物件,同時也會移除WeakMap集合中的鍵值對。但是隻有集合的鍵名遵從這個規則,鍵名對應的值如果是一個物件,則儲存的是物件的強引用,不會觸發垃圾回收機制

  • WeakMap 型別是一種儲存著許多鍵值對的無序列表,列表的鍵名必須是非null型別的物件,鍵名對應的值則可以是任意型別

  • WeakMap例項沒有size屬性

  • 增刪查

    	let key1 = {},
    		key2 = {},
    		map = new WeakMap([[key1, 'Hello'], [key2, 'Crane']]),
    		element = document.getElementById('id');
    	
    	if (map.has(key1)) {
    		console.log(map.get(key1));
    	}
    
    	map.set(element, 'Element');
    	element.parentNode.removeChild(element);
    
    	console.log(map.has(element))