基础梳理-map

58 阅读1分钟

Map特点

  1. 键值可以是任意类型,键唯一
  2. 有索引顺序,可迭代。而object则相反。
  3. 在涉及频繁添加和删除键值对的场景中表现更好,而object未做优化。

基本使用

const map1 = new Map()

map1.set('a', 'a')
map1.set(1, 1)
map1.set(null, null)

console.log(map1) 
// Map(3) { 'a' => 'a', 1 => 1, null => null }

console.log(map1.size)
// 3

// 使用for...of迭代
for(const val of map1) {
    console.log(val)
} 
// [ 'a', 'a' ]
// [ 1, 1 ]
// [ null, null ]

Map数据分类

const map2 = new Map()
map2.set('张三', '26')
map2.set('李四', '35')
map2.set('王五', '42')

const result = Map.groupBy(map2, ([key, val]) => val < 30 ? 'young age' : 'middle age')
console.log(result.get('young age'))
// [
//     [
//         "张三",
//         "26"
//     ]
// ]

Map.groupBy目前仍是实验性API,实际使用时需要注意兼容性。

跟object对比

const obj1 = {a: 'a', 1: 1, c: null}
// 错误写法❎: TypeError: obj1 is not iterable
// for(const val of obj1) {
//     console.log(val)
// } 

// 可以用Object.keys, Object.values, Object.entries获取自身的可枚举属性和值
console.log(Object.entries(obj1))
// [ [ '1', 1 ], [ 'a', 'a' ], [ 'c', null ] ] 

从输出可以看到Object对属性的排序有一套机制,最好不要依赖object属性的排序。

练习题

在对象数组里如何快速去除重复id的元素?

[{id: '1', name: 'aa'}, {id: '2', name: 'bb'}, {id: '1',name: 'cc'}]

篇外小知识

for...in会迭代可继承的非Symbol类型的枚举属性,在对象上谨慎使用。

const obj2  = {d: 'd', [Symbol('s')]: 's'}
Object.setPrototypeOf(obj1, obj2)

console.log(obj1)
// { '1': 1, a: 'a', c: null }

for(const val in obj1) {
    console.log(val)
}
// 1
// a
// c
// d