一、含義和基本用法
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
WeakMap
與 Map
基本一致,區別有兩點:
WeakMap
只接受對象作爲鍵名WeakMap
的鍵名是弱引用的,不計入垃圾回收機制。
如果需要暫時存放一些數據,那麼選用 WeakMap
就很合適了。常見的用途在於存放 DOM
節點。
WeakMap
沒有遍歷方法,也沒有 size
屬性。