在ES6以前,JavaScript通过Object
来实现"键值"的储存,但这种方式有一定的问题。
Map
是一种新的集合类型,也称映射。它带来了真正的"键值"储存机制。Map
的大多数特性可由Object
类型实现,但两者有细微的差距。
let m1=new Map()
//接收一个数组作为参数,该数组元素是表示键值对的数组
let m2=new Map([
["key1","value1"],
["key2","value2"],
["key3","value3"]
])
set(key,value)
:添加键/值对get(key)
:接受键名,获取对应值has(key)
:接受键名,判断是否存在该键/值对delete(key)
:接受键名,删除指定键/值对clear()
:清空实例中所有键/值对size
:获取映射中键值对的数量const m=new Map()
m.has("name") //false
m.get("name") //undefined
m.size //0
m.set("name","Matt") //添加键/值
m.has("name") //true
m.get("name") //Matt
m.size //1
m.delete("name") //删除键名为name的键/值对
m.clear() //清空m的键/值对
set()
会返回映射实例,因此可以把多个操作连起来const m=new Map()
m.set("name","Matt")
.set("age",16)
//对同一个键多次赋值,后面的值将覆盖前面的值
m.set("name","Matt")
.set("name","Amy")
与Object只能使用数值、字符串或符号作为键不同,Map可以使用任何JavaScript类型作为键。另外,只要内存地址不同,就视为两个键:
const m=new Map()
const functionKey=function(){}
const symbolKey=Symbol()
const objectKey=new Object()
m.set(functionKey,"functionValue")
m.set(symbolKey,"symbolValue")
m.set(objectKey,"objectValue")
m.get(functionKey) //functionValue
m.get(function(){}) //undefined
当修改映射中的键/值对的内容或属性时,映射本身保持不变:
const m=new Map()
const objKey={}
const objValue={}
m.set(objKey,objValue)
//修改键/值对的内容或属性
objKey.name="Matt"
objValue.hobby="read"
//依然可以获取
m.get(objKey) //{hobby:read}
entries()
:返回键/值的迭代器。(可用Symbol.iterator属性代替)
keys()
:返回键的迭代器
values()
:返回值的迭代器
forEach()
:遍历map的所有成员
let m=new Map([
["key1","value1"],
["key2","value2"],
["key3","value3"]
])
for(let item of m.entries()){
console.log(item)
}
//["key1","value1"]
//["key2","value2"]
//["key3","value3"]
for(let item of m[Symbol.iterator]()){
console.log(item)
}
//["key1","value1"]
//["key2","value2"]
//["key3","value3"]
for (let [key, value] of m) {
console.log(key, value);
}
//key1,value1
//key2,value2
//key3,value3
for(let item of m.keys()){
console.log(item)
}
//key1
//key2
//key3
for(let item of m.values()){
console.log(item)
}
//value1
//value2
//value3
m.forEach((val,key)=>console.log(`${key}->${val}`))
// key1->value1
// key2->value2
// key3->value3
与Object的主要差异是,Map实例会维护键/值对的插入顺序。
通过扩展运算符(...
)或Array.from()
实现转换:
let map = new Map([
["key1","value1"],
["key2","value2"],
["key3","value3"]
]);
console.log([...map]) //[["key1","value1"],["key2","value2"],["key3","value3"]]
console.log([...map.entries()]) //[["key1","value1"],["key2","value2"],["key3","value3"]]
console.log([...map.keys()]) //["key1","key2","key3"]
console.log([...map.values()]) //["value1","value2","value3"]
console.log(Array.from(map)) //[["key1","value1"],["key2","value2"],["key3","value3"]]
结合数组的map
方法、filter
方法,可以实现Map的遍历和过滤:
let m1=new Map().set(1,"one").set(2,"two").set(3,"three")
let m2=new Map(
[...m1].filter(([key,value])=>key<3)
)
let m3=new Map(
[...m1].map(([key,value])=>[key+1,value+"*"])
)
console.log(m1) //Map(3) {1 => "one", 2 => "two", 3 => "three"}
console.log(m2) //Map(2) {1 => "one", 2 => "two"}
console.log(m3) //Map(3) {2 => "one*", 3 => "two*", 4 => "three*"}
前提是键为字符串形式:
function mapToObj(map) {
let obj = Object.create(null);
for (let [k,v] of map) {
obj[k] = v;
}
return obj;
}
let m = new Map().set("name", "Matt").set("age", 16);
mapToObj(m) //{name: "Matt", age: 16}
function objToMap(obj) {
let map = new Map();
for (let k of Object.keys(obj)) {
map.set(k, obj[k]);
}
return map;
}
objToMap({name: "Matt", age: 16}) //Map(2) {"name" => "Matt", "age" => 16}
delete()
效率更高原文:https://www.cnblogs.com/sanhuamao/p/14403090.html