js ES6新数据结构 Map
ヤッハロー、Kaiqisanすうう、一つふつうの学生プログラマである,在ES6中同时出现了 Set和Map这两种新的对象,人们总是把它们放在一起说明,仿佛它们就是天生一对,但其实他们俩虽然看起来有点不同,但是深究起来发现,其实,嘛!共同点还是挺多的。
Map是一种新的数据结构,是一种全新的键值对的储存方式
下面为定义一个Map类型的数据集合的方式
let mapList = new Map([['name', 'tom'], ['uid', 1001]])
console.log(mapList)
// {"name" => "tom", "uid" => 1001}
它的表达方式与对象如出一辙,前面那个成员代表 “键”,后面那个成员代表**“值”,那么怎么将它转化为对象**呢?
function strMapToObj(strMap) {
let obj = {}
for (let [key, val] of strMap) { // 没什么便捷的方法,只能用这个最直接最简便的的迭代来实现
obj[key] = val
}
return obj
}
let mapList = new Map([['name', 'tom'], ['uid', 1001]])
let newObj = strMapToObj(mapList)
console.log(newObj); // 一个对象,此时,newObj = { name: 'tom', uid: 1001 }
这么看来,Map的优势就可以直接显示出来了------那就是咱可以在定义对象的键名的时候加入参数。因为在ES5之前,对象的键名一直都是定死的,只能直接写入一个固定的键名,是字符串,无法使用参数。
let i = 0
let mapList = new Map([[`num${i}`, i]])
for (i; i < 15; i++) {
mapList.set(`num${i}`, i) // 新增一个成员
}
console.log(mapList)
// {"num0" => 0}
// {"num1" => 1}
// {"num2" => 2}
// .........
// {"num13" => 13}
// {"num14" => 14}
// 把上面的Map对象转化为普通对象就变成了
// mapList = {
// num0: 0
// num1: 1
// ........
// num13: 13
// num14: 14
// }
这比使用直接定义对象的方法要来得方便多了,也不需要一个一个对象成员去手写,达到了量产对象成员的效果。
PS:这个Map对象的**"键"也不局限于字符串,可以是任何数据类型,当然也可以是对象**。
let mapList = new Map([[{name: 'tommy'}, 111]])
接下来,我们来康康这个Map对象的常用方法吧!
PS: 输入console.log(Map.prototype)就可以看到它的所有的方法。
set(key, val)
: 为当前Map对象新增一个成员并添置于末尾,它需要俩参数,分别为键和值
let mapList = new Map([['name', 'tommy'], ['uid', 100001]])
mapList.set('phoneNumber', 3838438)
console.log(mapList)
// {"name" => "tommy"}
// {"uid" => 100001}
// {"phoneNumber" => 3838438}
需要注意一点的就是它与对象一样,都是不容许有相同的键名的存在,如果存在了,就会被替换,且是后来居上,后面加进来的元素会替换掉前面加进来的元素。
- 情景1 — 在添加成员的时候产生重复
let mapList = new Map([['name', 'tommy'], ['uid', 100001]])
mapList.set('phoneNumber', 3838438)
mapList.set('phoneNumber', 1111111)
console.log(mapList)
// {"name" => "tommy"}
// {"uid" => 100001}
// {"phoneNumber" => 1111111}
- 情景2 — 在定义的时候就直接产生重复
let mapList = new Map([['name', 'tommy'], ['uid', 100001], ['uid', 111]])
mapList.set('phoneNumber', 3838438)
console.log(mapList)
// {"name" => "tommy"}
// {"uid" => 111}
// {"phoneNumber" => 3838438}
get(key)
: 查询是否有该键,如果有,就返回该键的值,如果没有就返回undefined
let mapList = new Map([['name', 'tommy'], ['uid', 100001], ['phoneNumber', 3838438]])
let res = mapList.get('uid')
let res2 = mapList.get('gender')
console.log(res, res2) // 100001, undefined
has(key)
: 查询是否有该键,如果有,就返回true,如果没有就返回false
let mapList = new Map([['name', 'tommy'], ['uid', 100001], ['phoneNumber', 3838438]])
let res = mapList.has('uid')
let res2 = mapList.has('gender')
console.log(res, res2) // true, false
PS:上面俩方法 has()
get()
的查询机制都和Set方法的 has方法一样 ---- 友情链接
delete(key)
: 查询相应的**“键”**,如果找到了就删除该元素,并返回true,如果找不到就返回false
let mapList = new Map([['name', 'tommy'], ['uid', 100001], ['phoneNumber', 3838438]])
let res = mapList.delete('name')
console.log(mapList, res) // {"uid" => 100001, "phoneNumber" => 3838438}, true
let res2 = mapList.delete('gender')
console.log(mapList, res) // {"uid" => 100001, "phoneNumber" => 3838438}, false
clear()
: 清除当前Map对象中所有的成员
let mapList = new Map([['name', 'tommy'], ['uid', 100001], ['phoneNumber', 3838438]])
mapList.clear()
console.log(mapList) // {}
除此之外,这个Map对象还拥有方法 entries()
forEach()
values()
keys()
以及迭代器 ,可以实现for in 和for of的迭代,但是无法实现数组的一般迭代方法比如map
filter
等等.
总结
在一些对象里面需要批量定义相似的对象名的时候或需要弹性定义某属性名的时候就需要这个Map对象了,批量定义上面有定义,这里就说明一下弹性定义属性名
let admin = new Map([['name', 'tommy'], ['uid', 100001]])
let NetEaseEmail = 'Kaiqisan@163.com'
mapList.set(NetEaseEmail ? 'NetEaseEmail': 'QQEmail', NetEaseEmail)
如果这个人使用了网易邮箱,admin的第三个**“键”**就是NetEaseEmail,如果使用了qq邮箱,这第三个"键"就是QQEmail。