ES6中Map和Set

前言 ◣

ES6是JavaScript語言的新標準,2015年6月正式發佈後,迅速推廣, 現在大多數瀏覽器都支持ES6中的大多數特性.
而本文將對ES6新增數據結構集Map和Set進行了解.

Map ◣

Map顧名思義,地圖本就有 一 一 對應的特點,就像字典一樣.
Map結構是鍵值的組合,它的key不止限於字符串類型 , key可以爲任何類型.[如下所示:]

    var m = new Map();
            
    var key1 = "String";  
    var key2 = {name:'李四'};   
    var key3 = function(){}; 
     
    m.set(key1, "value1"); //key爲字符串
    m.set(key2, "value2"); //key爲對象
    m.set(key3, "value3"); //key爲函數

    console.log(m.get(key1)); //value1
    console.log(m.get(key2)); //value2
    console.log(m.get(key3)); //value3

事實上Map的key是與內存地址綁定的,只要內存地址不一樣,就會視爲兩個鍵, 所以Map的key可以爲任何的數據類型.


Map常用操作方法:

set(key,val): 添加某個值,返回Map結構本身。
get(key)    : 讀取某個鍵,如果該鍵未知,則返回undefined
delete(key) : 刪除某個鍵,返回一個布爾值,判斷是否刪除成功。
has(key)    : 返回一個布爾值,判斷該值是否爲Map的鍵。
clear()     :  清除所有成員,沒有返回值。
屬性 size    :  返回映射對象中的鍵/值對的數目。

遍歷:

keys():返回鍵名的遍歷器。
values():返回鍵值的遍歷器。
entries():返回所有成員的遍歷器。
forEach():遍歷 Map 的所有成員。

還可以使用 for…of

var m = new Map();
 m.set('a', 1);
 m.set('b', 2);
for (var [key,value] of m) {
  console.log(key+":"+value);
}
//輸出 a:1 b:2 .

Map對象與其他數據結構轉換

  1. Map轉數組
let m = new Map([['name','張三'],['age','21']]);
console.log(...m)
//[['name','張三'],['age','21']]
  1. 數組轉Map
let ar = [['name','張三'],['age','21']];
let m = new Map(ar);
//Map(2) {"name" => "張三", "age" => "21"}
  1. Map轉對象
let m = new Map([['name','張三'],['age','21']]);

function method(map){
  let obj = Object.create(null); //創建一個空對象
  for(let [key,value] of map){
    obj[key] = value;
  }
  return obj
}
method(person);
//{name: "張三", age: "21"}
  1. 對象轉Map
let obj ={'name':'張三','age':'20'};

function method(ot){
  let m = new Map();
  for(let key of Object.keys(ot)){
    map.set(key,ot[key]);
  }
  return m
}
method(obj);

注意:

如果Map的鍵是一個基本類型的值(數字、字符串、布爾值),則只要兩個值嚴格相等,Map將其視爲一個鍵.。如 0 和 - 0 :
    var m = new Map(); 
    if(0 === -0)
     console.log("true");
    else
     console.log("false");
   //輸出 true
    m.set(0,3);
    m.set(-0,4);
    console.log(m.size);   // 1
    console.log(m.get(0)); // 4
    console.log(m.get(-0)) // 4

另外NaN不嚴格相等於自身,但Map將其視爲同一個鍵。

    var m = new Map(); 
    if(NaN===NaN)
     console.log("true");
    else
     console.log("false");
   //輸出 false
    m.set(NaN,3);
    m.set(NaN,4);
    console.log(m.size);      // 1
    console.log(m.get(NaN));  // 4
    console.log(m.get(NaN))   // 4

因爲Map的set方法返回的是Map本身,所以可以採用鏈式寫法。

var m = new Map();
m.set('num',1).set(1,"數字");
console.log(m.get(1)) //數字

WeakMap

提到 Map 不得不提到它兄弟 WeakMap
WeakMap 同樣是鍵值對集合 但它的key不能基本數據類型(數值,字符串等), 只能是對象 (不包括null). 方法也只有4個:

 set(key, val);
 get(key) ;
 has(key);
 delete(key);

此外它的 key 都是 弱引用 (這點與Map相反),說人話就是 WeakMap 內的東西垃圾回收時不考慮,使用它不用擔心內存泄漏問題。
注:(內存泄漏:申請的內存空間沒有被正確釋放,導致後續程序裏這塊內存被永遠佔用(不可達),而且指向這塊內存空間的指針不再存在時,這塊內存也就永遠不可達了,內存空間就這麼一點點被消耗);


Set ◣

Set數據結構是一個類似於數組,但是與數組不同的是它具有唯一性,裏面的元素都是不重複的,值可以是原始類型和引用類型.

Set常用操作方法:

set(key, value) : 設置key所對應的value值
get(key)        : 獲取key所對應的value值,若無則undefined
has(key)        :返回一個布爾值,判斷該值是否爲Map的鍵。	
delete(key)     : 刪除某個鍵,如刪除失敗返回false
clear()         : 清除所有成員
屬性 size       :  返回的是set實例的長度。

當然Set的用途不止這些,可以利用Set結構特性玩些不一樣的操作:

1.可以用它去除一組數據中重複的值.

let a = new Set([1,2,3,3,4,5,5,6,6,7]);
console.log([...a]);	//[1, 2, 3, 4, 5, 6, 7]

2.查找兩組數據中的交集

let a = new Set([1,2,3]);
let b = new Set([3,4,5]);
//交集
let value = new Set([...a].filter( item => b.has(item)));
console.log([...value]); //[3]]

3.查找兩組數據中的並集

let a = new Set([1,2,3]);
let b = new Set([3,4,5]);
//並集
let value = new Set([...a],[...b]);
console.log([...value]); //[1, 2, 3, 4, 5]

4.查找兩組數據中的差集

let a = new Set([1,2,3]);
let b = new Set([3,4,5]);
//差集
let value = new Set([...a].filter(item=>!b.has(item)));
console.log([...value]); //[1, 2]  這裏是b相對於a來說沒有的元素
補充 : 
 filter()是Array對象方法之一,
 filter() 方法創建一個新的數組,新數組中的元素是通過檢查指定數組中符合條件的所有元素。
語法:
  ..........................................................................
  array.filter(function(currentValue,index,arr), thisValue);
  ..........................................................................
  currentValue | 必須 | 當前元素的值
  index        | 可選 | 當前元素的索引值
  arr          | 可選 | 當前元素屬於的數組對象
  thisValue    | 可選 | 對象作爲該執行回調時使用,傳遞給函數,用作 "this" 的值。

如果省略了 thisValue ,“this” 的值爲 “undefined”

!!!注意:
    filter() 不會對空數組進行檢測。
    filter() 不會改變原始數組。

遍歷
Set 結構的實例同樣有四個遍歷方法,可以用於遍歷成員。

keys()   :返回鍵名的遍歷器 
values() :返回鍵值的遍歷器
entries():返回鍵值對的遍歷器
forEach():使用回調函數遍歷每個成員
-----------------------------------------------------------------
!!!注意: 由於Set沒有鍵名,只有值名,keys()和values()返回的結果是一樣.
-----------------------------------------------------------------

還可以使用 for…of

var s = new Set(1,2,3,4,5,6);
for (let val of s) {
  console.log(val);
 //1 2 3 4 5 6
}

這裏需要說下,Set的遍歷順序就是插入的順序,這個特性某些時候非常有用.


WeakSet

當然Set也有自己的同胞 WeakSet

一眼看去,WeakSet 是一個弱結構,與WeakMap相似,它的值是弱引用,則其引用不計入垃圾回收機制

除了定義不同之外,WeakSet沒有size屬性,也不可以進行遍歷操作,因爲它可能隨時會被回收,垃圾回收機制執行過後,元素個數可能不一樣.

常用操作方法

add()	: 添加新元素
delete(): 刪除WeakSet的成員
has()   : 判斷WeakSet是否含有某個元素

今天的分享到這就告一段落咯,之後還會繼續更新,歡迎大家繼續關注。

參考:
ES6 菜鳥教程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章