前面我们讲过一种条件语句的优化方式,利用映射(map)来替代多个 if…else 和 switch…case
function sayHi (name) {
return {
'tom': 'hello',
'hxh': 'hi',
'lucy': 'nihao'
}[name]
}这里我们用的 map 实际上就是一个简单的对象字面量,而你可能不知道的是,ES6 给我提供了一个真正的 Map 对象。语法为
new Map([iterable])比如通过二维数组来生成一个 Map 实例
new Map([
['name', 'tom'],
['age', 20]
])
// Map(2) {"name" => "tom", "age" => 20}那么有同学说了,既然已经有了 Object,为什么还要弄个新的 Map 对象出来呢?必然是因为这两则之间存在差异,接下来我们就来看看 Map 相对于 Object 有哪些优势。
增删改查
Map 对键值的增删改查并没有像 Object 那么随意,需要通过指定的方法来操作。
let myMap = new Map()
// 设置
myMap.set('name', 'Tom')
// 获取
myMap.get('name') // "Tom"
// 删除
myMap.delete('name')可以看到,Map 实际上是规范了上述操作,在涉及频繁增删键值对的场景下会有一定的性能优势。此外还有 clear() 这样的方法用来清空所有的健
myMap.clear()以及 has() 判断是否存在某个键
myMap.has('name')
// false键类型
众所周知,Object 的键只能是字符串(或 Symbols),而 Map 的键则可以是任何数据类型 ,
let myMap = new Map()
let k1 = () => {}
let k2 = {}
let k3 = new RegExp(/.+/)
myMap.set(k1, '函数')
myMap.set(k2, '对象')
myMap.set(k3, '正则')
myMap.get(k1) // "函数"
myMap.get(k2) // "对象"
myMap.get(k3) // "正则"注意,使用对象作为键的时候必须是原对象引用
myMap.get({}) // undefined
myMap.get(()=> {}) // undefined因为 k2 !== {},而 NaN 比较特殊,虽然 NaN === NaN 但是却会被当成同一个键
myMap.set(NaN, '非数字')
myMap.get(NaN) // "非数字"键顺序
前面我们讲过,遍历一个对象中的键并非和设置时一样,这里面存在一个重新排序的规则,比如
let obj = {
100: 'Tom',
10: 'Lucy'
}
Object.keys(obj)
// ["10", "100"]所以你是没办法保证按照原来的顺序遍历一个对象的,然而 Map 解决了这个问题,保证了设置和遍历的键顺序一致
let myMap = new Map()
myMap.set(100, 'Tom')
myMap.set(10, 'Lucy')
for (var key of myMap.keys()) {
console.log(key)
}
// 100
// 10可见,Map 的遍历顺序并没有受到键值的影响。注意,这里的 myMap.keys() 是一个迭代器,不是一个数组
myMap.keys()
// MapIterator {100, 10}如果你真想拿到键的数组,可以通过 Array.from() 方法做个转换
Array.from(myMap.keys())
// [100, 10]同样也可以拿到值的数组
Array.from(myMap.values())
// ["Tom", "Lucy"]数量
要获取一个对象的键值对数量,需要通过获取它的键或值的数组,然后取 length
Object.keys({
name: 'Tom',
age: 20
}).length
// 2而 Map 则直接提供了一个 size 属性
myMap.size
// 2遍历
Object 有个很大的遗憾是不能直接使用我们推荐的 for…of 进行遍历,而 Map 则完全可以享受这个功能,而且还有很多花样。
直接以[key, value] 遍历整个 Map 对象
let myMap = new Map()
myMap.set('name', 'Tom')
myMap.set('age', 20)
for (var [key, value] of myMap) {
console.log(key + " = " + value)
}
// name = Tom
// age = 20遍历键 keys()
for (var key of myMap.keys()) {
console.log(key)
}
// name
// age遍历值 values()
for (var value of myMap.values()) {
console.log(value)
}
// 'Tom'
// 20可见,在遍历迭代这一块,Map 有很大的优势。
最新评论