Map简介
es6之前,Js中实现“键/值”存储可以使用Object高效的完成。
es6之后,Map作为一种新的集合类型,为这门语言带来了真正的键/值存储机制。
关系:Map的大多数特性都可以通过Object类型来实现,但两者仍有一些细微的差异。
基本使用
创建一个空映射
const m = new Map()
同时也可以传一个可迭代的对象,例如
const m = new Map([
["name":"map"],
["age":"es6"]
])
alsert(m.size) // 2
映射期待的键值对,无论是否提供
const m = new Map([[]])
alert(m.has(undefined)) // true
初始化之后,我们可以通过set()
方法再添加键值对,以及他身上的get()、has()、delete()、clear()
const m = new Map()
alert(m.size) // 0
alert(m.has("name")) //false
alert(m.get("name")) //false
m.set("name","ckj")
.set("age","21")
alert(m.size) // 2
alert(m.has("name")) //true
alert(m.get("name")) //ckj
m.delete("name") // 只删除此键值对
alert(m.size) // 1
alert(m.has("name")) //false
alert(m.has("age")) //true
m.clear() //清除所有
alert(m.size) // 0
alert(m.has("name")) //false
alert(m.has("age")) //false
set()方法返回映射实例,因此可以吧多个操作连缀起来,包括初始化声明:
const m = new Map().set("name","ckj")
m.set("age",21).set("gender","male")
alert(m.size) //3
总结
与Object只能使用数值,字符串或符号作为键不同,Map可以使用任何Js数据类型作为键。
顺序和迭代
与Object一个主要差异是,Map实例会维护键值对的插入顺序,因此可以根据插入顺序执行迭代操作
使用迭代器
const m = new Map([
["name","ckj"],
["age",21],
["gender","male"]
])
alert(m.entries === m[Symbol.iterator]) //true
for (let item of m.entries){
alert(item)
}
// ["name","ckj"],
// ["age",21],
// ["gender","male"]
for (let item of m[Symbol.iterator]){
alert(item)
}
// ["name","ckj"],
// ["age",21],
// ["gender","male"]
将映射转换为数组可以直接使用扩展console.log([...m]) // ["name","ckj"],["age",21],["gender","male"]
使用回调函数
const m = new Map([
["name","ckj"],
["age",21],
["gender","male"]
])
m.forEach((val,key) => alert(`${key} -- ${val}`))
// "name" -- "ckj",
// "age" -- 21,
// "gender" -- "male"
keys()
和 values()
分别返回以插入顺序生成键和值的迭代器
for (let key of m.keys()){
alert(key)
}
// "name"
// "age"
// "gender"
for (let value of m.values()){
alert(value)
}
// "ckj"
// 21
// "male"
键和值在迭代器遍历的时候是可以修改的,但在映射内部的引用则无法修改。不过仍然可以改变它对象内部的属性,例如
const m = new Map([
["name","ckj"]
])
for (let key of m.keys()){
key = 'newName'
alert(key) // newName
alert(m.get("name")) // ckj
}
const obj = {age:21}
const m1 = new Map([
[obj,123]
])
for (let key of m1.keys()){
key.age = 22
alert(key) // {age:22}
alert(m.get(obj)) // 123
}
alert(obj) //{age:22}
选择Object还是Map?
选择 **个人偏好,影响不大 **,但从内存和性能上来讲,确实有明显的差别
- 内存占用
Map大约可以比Object多存储50%的键值对
- 插入性能
Map在所有浏览器中一般会稍微快一点,所以如果代码涉及大量插入操作的话,Map会更加优秀一点
- 查找速度
Object在代码涉及大量查找操作的时候会更加快一点
- 删除性能
Map的delete()操作都比插入和查找快,涉及大量删除操作的话,毫无以为的选择Map