前言 ◣
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對象與其他數據結構轉換
- Map轉數組
let m = new Map([['name','張三'],['age','21']]);
console.log(...m)
//[['name','張三'],['age','21']]
- 數組轉Map
let ar = [['name','張三'],['age','21']];
let m = new Map(ar);
//Map(2) {"name" => "張三", "age" => "21"}
- 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"}
- 對象轉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 菜鳥教程