ES6 提供了 Map 數據結構。是鍵值對的集合,Map類似於對象,但是其鍵的範圍不限於對象的字符串,各種類型的值(包括對象)都可以當作鍵。
一.Map數據結構
1.基本定義
- ① Map數據結構的定義
//例一 創建一個的Map空集合,使用常規的set,get,has,delete方法操作 const m = new Map(); const 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對象 const map = new Map([ ['name', 'Joey'], ['title', 'Author'] ]); map.size // 2 map.has('name') // true map.get('name') // "張三" map.has('title') // true map.get('title') // "Author" // 例三 任何具有 Iterator 接口、且每個成員都是一個雙元素的數組的數據結構,都可以當作Map構造函數的參數。這就是說,Set和Map都可以用來生成新的 Map。 const set = new Set([ ['foo', 1], ['bar', 2] ]); const m1 = new Map(set); m1.get('foo') // 1 const m2 = new Map([['baz', 3]]); const m3 = new Map(m2); m3.get('baz') // 3
2.Map數據結構的特性
-
① Map數據結構也是鍵值對的集合,與對象結構類似,但是對象結構只能使用字符串或者Symbol當做鍵,而Map的鍵可以是隨意的值或者結構。
es5中對象作爲key值,自動轉換爲字符串存儲 const data = {}; const element = document.getElementById('myDiv'); data[element] = 'metadata'; data['[object HTMLDivElement]'] // "metadata"
-
② Map數據結構key的唯一性,多次賦值,後面的值將覆蓋前面的值。
const map = new Map(); map .set(1, 'aaa') .set(1, 'bbb'); map.get(1) // "bbb"
-
③ 若讀取的是一個未知的鍵,則返回
undefined
new Map().get('asfddfsasadf') // undefined
-
④ 若map結構中key引用的不是同一地址的對象,則視爲2個鍵。
//一 const map = new Map(); map.set(['a'], 555); map.get(['a']) // undefined //二 const map = new Map(); const k1 = ['a']; const k2 = ['a']; map .set(k1, 111) .set(k2, 222); map.get(k1) // 111 map.get(k2) // 222
-
⑤ 針對於基礎類型
0
,-0
,+0
爲同一值;undefined
與null
不爲同一值;雖然NaN不嚴格相等於自身,但 Map 將其視爲同一個鍵。let map = new Map(); map.set(-0, 123); map.get(+0) // 123 map.set(true, 1); map.set('true', 2); map.get(true) // 1 map.set(undefined, 3); map.set(null, 4); map.get(undefined) // 3 map.set(NaN, 123); map.get(NaN) // 123
3.Map結構的常規方法
-
Map
size 屬性
:返回 Map 結構的成員總數。
Map.prototype.set(key, value)
:set方法設置鍵名key對應的鍵值爲value,然後返回整個 Map 結構。因此可以採用鏈式寫法。
Map.prototype.get(key)
:get方法讀取key對應的鍵值,如果找不到key,返回undefined。
Map.prototype.has(key)
:has方法返回一個布爾值,表示某個鍵是否在當前 Map 對象之中。
Map.prototype.delete(key)
:delete方法刪除某個鍵,返回true。如果刪除失敗,返回false。
Map.prototype.clear()
:clear方法清除所有成員,沒有返回值。 -
範例
//1.size const map = new Map(); map.set('foo', true); map.set('bar', false); map.size // 2 //2.set let map = new Map() .set(1, 'a') .set(2, 'b') .set(3, 'c'); //3.get const m = new Map(); const hello = function() {console.log('hello');}; m.set(hello, 'Hello ES6!') // 鍵是函數 m.get(hello) // Hello ES6! //4.has const m = new Map(); m.set('edition', 6); m.set(262, 'standard'); m.set(undefined, 'nah'); m.has('edition') // true m.has('years') // false m.has(262) // true m.has(undefined) // true //5.delete const m = new Map(); m.set(undefined, 'nah'); m.has(undefined) // true m.delete(undefined) m.has(undefined) // false //6.clear let map = new Map(); map.set('foo', true); map.set('bar', false); map.size // 2 map.clear() map.size // 0
4.Map數據結構的遍歷
-
Map 結構的實例有四個遍歷方法
Map.prototype.keys()
:返回鍵名的遍歷器
Map.prototype.values()
:返回鍵值的遍歷器
Map.prototype.entries()
:返回鍵值對的遍歷器
Map.prototype.forEach()
:使用回調函數遍歷每個成員 -
keys(),values(),entries()遍歷範例
//一 keys const map = new Map([ ['F', 'no'], ['T', 'yes'], ]); for (let key of map.keys()) { console.log(key); } // "F" // "T" //二 values for (let value of map.values()) { console.log(value); } // "no" // "yes" //三 entries 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() 因爲 Map 結構的默認遍歷器接口(Symbol.iterator屬性),就是entries方法。 for (let [key, value] of map) { console.log(key, value); } // "F" "no" // "T" "yes" map[Symbol.iterator] === map.entries // true
-
forEach使用回調函數的方式進行遍歷,參數依次是value值,key值,map對象
map.forEach(function(value, key, map) { console.log("Key: %s, Value: %s", key, value); });
-
forEach方法還可以接受第二個參數,用來綁定this。
//下面代碼中,forEach方法的回調函數的this,就指向reporter。 const reporter = { report: function(key, value) { console.log("Key: %s, Value: %s", key, value); } }; map.forEach(function(value, key, map) { this.report(key, value); //this爲{report: ƒ} }, reporter);