【ES6系列】詳解ES6中的Map

一、含義和基本用法

Map 類似於對象,都用於存儲 key-value 結構的數據。但是,在傳統的對象上,只能用字符串或者 symbol 來作爲鍵名。然而,Map 與對象最大的差別就在於它可以各種數據類型作爲鍵名。

Map 是一個構造函數,用於實例化實例。

const m = new Map()
const o = {name:"jonas"}

m.set(o, 'content')
m.get(o) //content

除此以外,Map() 可以接收一個可迭代對象(前提是每個成員都是一個雙元素結構的迭代對象)作爲參數以初始化。

const map = new Map([
  ['name', '張三'],
  ['title', 'Author']
]);

map.get('name') //張三
map.get('title') //Author

注意:

  • 如果 map 中存在相同的鍵名(比較規則是棧內存中是否一致,只要內存地址不一樣,就視爲兩個鍵),則後面的賦值會覆蓋前面的
  • 如果讀取一個未知的鍵,則返回 undefined

二、實例屬性和方法

  • size 屬性可以返回 map 的長度。
  • Map.prototype.set(key,value) —— 添加或修改鍵值對,返回值是當前的集合,所以可以採用鏈式調用。
  • Map.prototype.get(key) —— 根據 key 獲取 value
  • Map.prototype.has(key) —— 是否含有鍵名 key,返回布爾值
  • Map.prototype.delete(key) —— 刪除某個 key-value
  • Map.prototype.clear() —— 清空集合
  • Map.prototype.keys() —— 返回鍵名的遍歷器
  • Map.prototype.values() —— 返回鍵值的遍歷器
  • Map.prototype.entries() —— 返回鍵值對的遍歷器
  • Map.prototype.forEach() —— 遍歷集合

三、類型轉換

1.Map 轉換爲數組

也許你會覺得奇怪,像 Set 那種只保存值的有序數據結構轉換爲數組是很好理解的,但是 Map 是一種鍵值對結構的數據,那麼轉換爲數組以後成什麼樣呢??

答案是一個二維數組,元素都是數組,數組有兩個元素,第一個元素就是鍵名,第二個元素就是鍵值。

const map = new Map()
map.set(1,'a')
    .set({"name":"jonas"},{"age":18})
console.log([...map]) //[ [ 1, 'a' ], [ { name: 'jonas' }, { age: 18 } ] ]

2.Map 轉換爲對象

如果所有的鍵名都是字符串,那麼這個 map 可以直接轉換爲對象,如果鍵名存在非字符串,則先把鍵名轉換爲字符串,再轉換爲對象。

官方沒有提供直接轉換的方法,所以此處還是自己手動寫了方法實現:

/**
 * 將map轉換爲普通對象
 * @param map
 * @return obj 
 */
function mapToObj(map) {
    if(getType(map) !== "Map")
        throw new Error("map is not a Map")
    let obj = {}
    map.forEach((value,key) => {
        if(getType(key) !== "String")
            key = Object.prototype.toString.call(key)
        obj[key] = value
    })
    function getType(obj) {
        return Object.prototype.toString.call(obj).slice(8,-1)
    }
    return obj
}

const map = new Map()
map.set("name","jonas")
    .set({age:18},[])
const obj = mapToObj(map)
console.log(obj) //{ name: 'jonas', '[object Object]': [] }

3.對象轉換爲 Map

一行代碼解決:

new Map(Object.entries(obj))

WeakMap

WeakMapMap 基本一致,區別有兩點:

  • WeakMap 只接受對象作爲鍵名
  • WeakMap 的鍵名是弱引用的,不計入垃圾回收機制。

如果需要暫時存放一些數據,那麼選用 WeakMap 就很合適了。常見的用途在於存放 DOM 節點。

WeakMap 沒有遍歷方法,也沒有 size 屬性。

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