帶你玩轉 JavaScript ES6 (六) – Map 對映

NO IMAGE

本文同步帶你入門 帶你玩轉 JavaScript ES6 (六) – Map 對映,轉載請註明出處。

本章我們講學習 ES6 中的 Map(對映)。上一章節我們學習了 [Set(集合)]()的相關內容,如果說 Set 類似於陣列,那麼 Map 就類似於物件。

一、 概念

Map 是一個可以儲存鍵值對的物件。其中鍵和值都可以是物件、原始值或二者的結合。

先看一個簡單的示例,來了解 Map 基本用法:

// 申明 map 例項
let departments = new Map()
// 向 map 中新增元素
departments.set("UX", {
'name': 'UX Center',
'employees': 48
})
departments.set('dev', {
'name': 'Research & Development Center',
'employees': 200    
})
console.log(departments)// Map {"UX" => Object {name: "UX Center", employees: 48}, "dev" => Object {name: "Research & Development Center", employees: 200}}
console.log(typeof departments)// object

本質上 Map(對映) 就是一個 object(物件),在 ES6 以前,我們通常會使用 object 模擬出類似 Map 的資料結構。

二、 Map 對映常用操作

常用的 Map 操作有:set(key, value) 修改, get(key) 獲取, delete(key) 刪除, has(key) 判斷是否存在, values() 獲取所有值和 clear() 清空 Map 等。

2.1 初始化

// 申明一個 Map
let m = new Map()
console.log(m)

2.2 設定和獲取值

① 使用 map.set(key, value) 設定新值或更新值

// 申明 Map
let students = new Map();
// 設定值
students.set('huliuqing', {
name: 'huliuqing',
age: 18
})
students.set('zhangsanfeng', {
name: '張三丰',
age: 128
})
console.log(students)// Map {"huliuqing" => Object {name: "huliuqing", age: 18}, "zhangsanfeng" => Object {name: "張三丰", age: 128}}
// 重複設定值, 如果鍵值存在則新值替換舊值
students.set('huliuqing', {
name: 'huliuqing',
age: 16
})
console.log(students)// Map {"huliuqing" => Object {name: "huliuqing", age: 16}, "zhangsanfeng" => Object {name: "張三丰", age: 128}}

② 使用 get(key) 獲取值,如果獲取的 key->value 不存在返回 undefined

let students = new Map();
students.set('huliuqing', {
name: 'huliuqing',
age: 18
})
// 分別獲取 huliuqing ,zhangsanfeng
console.log(students.get('huliuqing'))// {name: "huliuqing", age: 18}
console.log(students.get('zhangsanfeng'))// undefined

2.3 判斷是否存在

使用 map.has(key) 判斷給定 key 是否存在 Map(對映) 內。

let students = new Map();
students.set('huliuqing', {
name: 'huliuqing',
age: 18
})
console.log(students)// Map {"huliuqing" => Object {name: "huliuqing", age: 18}}
console.log(students.has('huliuqing'))// true
console.log(students.has('zhangsanfeng'))// false

2.4 刪除

方法 map.delete(key) 刪除給定 key 的鍵值對,並返回成功或失敗結果。

成功返回 true; 失敗或key不存在返回 false。

let students = new Map();
students.set('huliuqing', {
name: 'huliuqing',
age: 18
})
console.log(students)// Map {"huliuqing" => Object {name: "huliuqing", age: 
// 刪除
let deleted = students.delete('zhangsanfeng')
console.log(`deleted zhangshanfeng: ${deleted}`)
console.log(students)// Map {"huliuqing" => Object {name: "huliuqing", age: 
deleted = students.delete('huliuqing')
console.log(`deleted huliuqing: ${deleted}`)
console.log(students)// Map {} 

2.5 清空對映

使用 map.clear() 清空 Map 對映內所有元素

let students = new Map();
students.set('huliuqing', {
name: 'huliuqing',
age: 18
})
students.set('zhangsanfeng', {
name: '張三丰',
age: 128
})
console.log(students)// Map {"huliuqing" => Object {name: "huliuqing", age: 18}, "zhangsanfeng" => Object {name: "張三丰", age: 128}}
// 清空
students.clear();
console.log(students);// Map {}

2.6 獲取 Map 中元素個數

使用 map.size 可以獲取當前 Map 中有多少個元素

三、 Map(對映) 的遍歷

由於 Map 同 Set 一樣,是一個可迭代物件,所以可以使用 for of 迭代語法 對其迭代獲取所有值

let pets = new Map()
pets.set('cat', {
name: 'lily' ,
age: 2
})
pets.set('dog', {
name: 'cat',
age: 1
})
for (pet of pets) {
console.log(pet)// ["cat", Object]; ["dog", Object]
}
for (let [name, pet] of pets) {
console.log(`${name} : ${pet}`)//cat : [object Object]; dog : [object Object]
}

四、 Object 與 Map 異同

由於 Map 本質是 Object 物件,雖然以前我們也拿 Object 當 Map 來使用,但是相比 Object 物件,Map 有一下特點:

4.1 object 與 map 異同

object 通常有原型即物件例項有 prototype 屬性,Map 無 prototype 屬性。雖然 ES5 開始可以使用 map = Object.create(null) 建立無 prototype 的物件。
Map 的鍵名可以是物件、原始值或二者的結合,而物件的屬性只能是 string 或 symbols 型別(Symbol 型別為 ES6 新的基礎資料型別)。
Map 使用 size 屬性可以非常用以獲取鍵值對個數。而物件僅能手動確認。

4.2 如何選擇 Map 或 Object

如果你需要解決下面這些問題,那麼果斷擁抱 Map。

- 在執行之前 key 是否是未知的,是否需要動態地查詢 key 呢?
- 是否所有的值都是統一型別,這些值可以互換麼?
- 是否需要不是字串型別的 key ?
- 鍵值對經常增加或者刪除麼?
- 是否有任意個且非常容易改變的鍵值對?
- 這個集合可以遍歷麼(Is the collection iterated)?

五、 WeakMap

WeakMap 解構同 Map 結構類似,不同點在於 WeakMap 鍵名僅支援物件和null

參考資料

MDN Map