Map
與Set
是es6
提供兩種新的數據結構
這個單元將討論他們與Array
, Object
的差異
以及我們可以在什麼情況使用它們。
Map
跟物件非常相近,當我們需要鍵值時常會用到物件
但物件有幾個缺點
Map
能夠解決這些缺點,尤其是能夠將物件設為鍵的特性更是好用new Map([iterable])
Iterable 是一個陣列或其他iterable物件
,該物件的元素皆是鍵/值成對的(例如兩個元素的陣列)
成對的鍵/值會被新增到新的Map。null會被作為undefined
const u1 = {name: 'Peter'}
const u2 = {name: 'Sam'}
const u3 = {name: 'Cindy'}
// 建構式賦值
const userRoles = new Map([
[u1, 'User'], [u2, 'User'], [u3, 'Admin']
])
/*
| 使用set方法逐一賦值
*/
userRoles.set(u1, 'User')
userRoles.set(u2, 'User')
userRoles.set(u3, 'Admin')
/*
| 使用set方法鏈接賦值
*/
userRoles.set(u1, 'User')
.set(u2, 'User')
.set(u3, 'Admin')
// 以上三種方式都會得到一樣的結果
const userRolesSize = userRoles.size
console.log(userRolesSize) // 3
/*
| 使用get方法取得鍵值
*/
console.log(userRoles.get(u1)) // "User"
/*
| 使用has方法確認鍵是否存在
*/
const u100 = {name: 'Hank'}
console.log(userRoles.has(u1)) // true
console.log(userRoles.has(u100)) // false
console.log(userRoles.get(u100)) // undefined
/*
| 使用has方法確認鍵是否存在
*/
const u100 = {name: 'Hank'}
console.log(userRoles.has(u1)) // true
console.log(userRoles.has(u100)) // false
console.log(userRoles.get(u100)) // undefined
/*
| 使用keys方法取得map鍵
*/
for(let u of userRoles.keys())
console.log(u.name)
// "Peter"
// "Sam"
// "Cindy"
/*
| 使用values方法取得map值
*/
for(let v of userRoles.values())
console.log(v)
// "User"
// "User"
// "Admin"
/*
| 使用entries方法取得項目陣列
*/
for(let [u, r] of userRoles.entries())
console.log(`${u.name} is ${r}`)
// Peter is User
// Sam is User
// Cindy is Admin
/*
| entries方法是map預設迭代器
| 因此其實上面例子我們可以省略entries()
*/
for(let [u, r] of userRoles)
console.log(`${u.name} is ${r}`)
// Peter is User
// Sam is User
// Cindy is Admin
/*
| 我們可以使用擴張運算子來將map轉為陣列
*/
console.log([...userRoles.keys()])
// [ { name: 'Peter' }, { name: 'Sam' }, { name: 'Cindy' } ]
console.log([...userRoles.values()])
// [ 'User', 'User', 'Admin' ]
console.log([...userRoles])
// [ [ { name: 'Peter' }, 'User' ],
// [ { name: 'Sam' }, 'User' ],
// [ { name: 'Cindy' }, 'Admin' ] ]
/*
| 使用delete方法刪除項目
*/
userRoles.delete(u1)
console.log(userRoles.has(u1)) // false
/*
| 使用clear方法刪除所有項目
*/
userRoles.clear()
console.log(userRoles.size) // 0
Set
類似Array
, 但其中元素的值都會是唯一不重複的Set
甚至可以搭配Array
使用,例如將Array
的值unique
new Set([iterable])
Set
接受一個可迭代
的參數或是null
或是不給予
且建構式將回傳一個Set
物件實例
const setArr1 = new Set()
console.log(setArr1)
// [object Set]
const arr = [1, 2, 3, 4, 5, 5, 5]
const setArr2 = new Set(arr)
for (let i of setArr2) {
console.log(i)
}
// 1 2 3 4 5
前面我們提到,Set
的值將會唯一,但給予的參數不會自轉型別
因此數字5
與字串5
將被視為不同的兩個值。
const set = new Set()
/*
| add 方法新增元素
*/
set.add(1)
set.add(2)
console.log(set.size) // 2
/*
| add 方法也可以使用串接的方式
*/
set.add(5)
.add('5')
console.log(set.size) // 4
/*
| 試著加入相同屬性驗證set不會記錄相同項目
*/
set.add('5')
console.log(set.size) // 4
/*
| delete 方法移除set中的元素,返回true/false
*/
console.log(set.delete(1)) // true
console.log(set.delete('apple')) // false
console.log(set.size) // 3
還有另外兩個類別稱為WeakMap與WeakSet
他們的用途沒那麼的廣泛,有興趣的朋友請自行查閱相關文件。
資料來源: JavaScript學習手冊, MDN