ES6中Set和Map用法例項詳解
本文例項講述了ES6中Set和Map用法。分享給大家供大家參考,具體如下:
Set
ES6提供了新的資料結構Set。它類似於陣列,但是成員的值都是唯一的,沒有重複的值。
Set函式可以接受一個數組(或類似陣列的物件)作為引數,用來初始化。
// 例一 var set = new Set([1,2,3,4,4]); [...set] // [1,4] var s = new Set(); [2,5,2].map(x => s.add(x)); for (let i of s) { console.log(i); } // 2 3 5 4
注:在Set內部,兩個NaN
是相等。兩個物件總是不相等的
let set = new Set(); let a = NaN; let b = NaN; set.add(a); set.add(b); set // Set {NaN}
let set = new Set(); set.add({}); set.size // 1 set.add({}); set.size // 2
var arr=[ {id:1,name:'葉落森'},{id:2,{id:3,{id:4,name:'葉落森'} ] const s = new Set(); arr.forEach(x => s.add(x)); for (let i of s) { console.log(i); }
四個操作方法:
add(value)
:新增某個值,返回Set結構本身。delete(value)
:刪除某個值,返回一個布林值,表示刪除是否成功。has(value)
:返回一個布林值,表示該值是否為Set
的成員。clear()
:清除所有成員,沒有返回值
let s = new Set(); s.add(1).add(2).add(2); // 注意2被加入了兩次 s.size // 2 s.has(1) // true s.has(2) // true s.has(3) // false console.log(s.delete(2));//true s.has(2) // false
set內部的元素可以遍歷for...of...
遍歷操作
Set 結構的例項有四個遍歷方法,可以用於遍歷成員。
keys()
:返回鍵名的遍歷器values()
:返回鍵值的遍歷器entries()
:返回鍵值對的遍歷器forEach()
:使用回撥函式遍歷每個成員
需要特別指出的是,Set
的遍歷順序就是插入順序。這個特性有時非常有用,比如使用 Set 儲存一個回撥函式列表,呼叫時就能保證按照新增順序呼叫。
(1)keys()
,values()
,entries()
keys
方法、values
方法、entries
方法返回的都是遍歷器物件。由於 Set 結構沒有鍵名,只有鍵值(或者說鍵名和鍵值是同一個值),所以keys
方法和values
方法的行為完全一致。
let set = new Set(['red','green','blue']); for (let item of set.keys()) { console.log(item); } // red // green // blue for (let item of set.values()) { console.log(item); } // red // green // blue for (let item of set.entries()) { console.log(item); } // ["red","red"] // ["green","green"] // ["blue","blue"]
Set 結構的例項預設可遍歷,它的預設遍歷器生成函式就是它的values
方法。
這意味著,可以省略values
方法,直接用for...of
迴圈遍歷 Set。
let set = new Set(['red','blue']); for (let x of set) { console.log(x); } // red // green // blue
Set 結構的例項與陣列一樣,也擁有forEach
方法,用於對每個成員執行某種操作,沒有返回值
set = new Set([1,9]); set.forEach((value,key) => console.log(key + ' : ' + value)) // 1 : 1 // 4 : 4 // 9 : 9
Map
Map結構提供了“值—值”的對應,是一種更完善的Hash結構實現。如果你需要“鍵值對”的資料結構,Map比Object更合適。它類似於物件,也是鍵值對的集合,但是“鍵”的範圍不限於字串,各種型別的值(包括物件)都可以當作鍵。
var m = new Map(); var o = {p: "Hello World"}; m.set(o,"content") m.get(o) // "content" m.has(o) // true m.delete(o) // true m.has(o) // false
注意,只有對同一個物件的引用,Map結構才將其視為同一個鍵。這一點要非常小心。
var map = new Map(); map.set(['a'],555); map.get(['a']) // undefined
上面程式碼的set和get方法,表面是針對同一個鍵,但實際上這是兩個值,記憶體地址是不一樣的,因此get方法無法讀取該鍵,返回undefined。
注:如果Map的鍵是一個簡單型別的值(數字、字串、布林值),則只要兩個值嚴格相等,Map將其視為一個鍵,包括0和-0。另外,雖然NaN不嚴格相等於自身,但Map將其視為同一個鍵。
例項屬性和方法:size、set、get、has、delete、clear
遍歷方法:keys()、values()、entries()、forEach()
const map = new Map([ ['F','no'],['T','yes'],]); for (let key of map.keys()) { console.log(key); } // "F" // "T" for (let value of map.values()) { console.log(value); } // "no" // "yes" for (let item of map.entries()) { console.log(item[0],item[1]); } // "F" "no" // "T" "yes" // 或者 for (let [key,value] of map.entries()) { console.log(key,value); } // "F" "no" // "T" "yes" // 等同於使用map.entries() for (let [key,value] of map) { console.log(key,value); } // "F" "no" // "T" "yes"
Map 結構轉為陣列結構,比較快速的方法是使用擴充套件運算子(...
)。
const map = new Map([ [1,'one'],[2,'two'],[3,'three'],]); [...map.keys()] // [1,3] [...map.values()] // ['one','two','three'] [...map.entries()] // [[1,'three']] [...map] // [[1,'three']]
結合陣列的map
方法、filter
方法,可以實現 Map 的遍歷和過濾(Map 本身沒有map
和filter
方法)。
const map0 = new Map() .set(1,'a') .set(2,'b') .set(3,'c'); const map1 = new Map( [...map0].filter(([k,v]) => k < 3) ); // 產生 Map 結構 {1 => 'a',2 => 'b'} const map2 = new Map( [...map0].map(([k,v]) => [k * 2,'_' + v]) ); // 產生 Map 結構 {2 => '_a',4 => '_b',6 => '_c'}
此外,Map 還有一個forEach
方法,與陣列的forEach
方法類似,也可以實現遍歷。
map.forEach(function(value,key,map) { console.log("Key: %s,Value: %s",value); });
區別:
set是一種關聯式容器,其特性如下:
- set以RBTree作為底層容器
- 所得元素的只有key沒有value,value就是key
- 不允許出現鍵值重複
- 所有的元素都會被自動排序
- 不能通過迭代器來改變set的值,因為set的值就是鍵
map和set一樣是關聯式容器,它們的底層容器都是紅黑樹,區別就在於map的值不作為鍵,鍵和值是分開的。它的特性如下:
- map以RBTree作為底層容器
- 所有元素都是鍵+值存在
- 不允許鍵重複
- 所有元素是通過鍵進行自動排序的
- map的鍵是不能修改的,但是其鍵對應的值是可以修改的
weakset
WeakSet結構與Set類似,也是不重複的值的集合。
WeakSet和Set的區別:
- WeakSet的成員只能是物件,而不能是其他型別的值
- WeakSet中的物件都是弱引用,即垃圾回收機制不考慮WeakSet對該物件的引用,也就是說,如果其他物件都不再引用該物件,那麼垃圾回收機制會自動回收該物件所佔用的記憶體,不考慮該物件還存在於WeakSet之中。這個特點意味著,無法引用WeakSet的成員,因此WeakSet是不可遍歷的。
WeakMap可以參考WeakSet
感興趣的朋友可以使用線上HTML/CSS/JavaScript程式碼執行工具:http://tools.jb51.net/code/HtmlJsRun測試上述程式碼執行效果。
更多關於JavaScript相關內容可檢視本站專題:《JavaScript操作DOM技巧總結》、《JavaScript頁面元素操作技巧總結》、《JavaScript事件相關操作與技巧大全》、《JavaScript查詢演算法技巧總結》、《JavaScript資料結構與演算法技巧總結》、《JavaScript遍歷演算法與技巧總結》及《JavaScript錯誤與除錯技巧總結》
希望本文所述對大家JavaScript程式設計有所幫助。