Map特点
- 键值可以是任意类型,键唯一
- 有索引顺序,可迭代。而object则相反。
- 在涉及频繁添加和删除键值对的场景中表现更好,而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