概念
是ES6新增的数据结构,用于存储映射关系。效果类似于对象,用于保存多个key:value形式的数据。在map中,我们称每个数据为一个键值对。map跟对象很很大不同
但是我们可能会想,在之前我们可以使用对象来存储映射关系,他们有什么区别呢?
事实上我们对象存储映射关系只能用字符串(ES6新增了Symbol )作为属性名( key ) ;
某些情况下我们可能希望通过其他类型作为key,比如对象,这个时候会自动将对象转成字符串来作为key ;
特点
- 对象保存键值对,并且能够记住键的原始插入顺序
- map集合中不能有重复的键名。
- 键值对,键可以是任意数值类型,而原生对象中的属性名只能是字符串
和Object对比
|
| Map | Object | | —- | —- | —- | | 意外的键 |Map
默认情况不包含任何键。只包含显式插入的键。 | 一个Object有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
注意: 虽然 ES5 开始可以用Object.create(null)来创建一个没有原型的对象,但是这种用法不太常见。 | | 键的类型 | 一个Map
的键可以是任意值,包括函数、对象或任意基本类型。 | 一个Object
的键必须是一个[String](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String)
或是[Symbol](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol)
。 | | 键的顺序 |Map中的 key 是有序的。因此,当迭代的时候,一个Map对象以插入的顺序返回键值。 | 一个Object的键是无序的
注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。 | | Size |Map
的键值对个数可以轻易地通过[size](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map/size)
属性获取 |Object
的键值对个数只能手动计算 | | 迭代 |Map
是 iterable 的,所以可以直接被迭代。 | 迭代一个Object
需要以某种方式获取它的键然后才能迭代。 | | 1、内存性能 | 给定固定大小的内存Map 大约可以比 Object 多存储 50%的键/值对 | 不同浏览器差异很大 | | 2、插入、删除性能 | 在频繁增删键值对的场景下表现更好。 | 在频繁添加和删除键值对的场景下未作出优化。 | | 3、查找性能 | 从大型 Object 和 Map 中查找键/值对的性能差异极小 | 代码涉及大量查找操作,那么某些情况下可能选择 Object 更好一些。 |
使用
1、创建
let newMap = new Map();
也可以创建时初始化里面的元素
let newMap = new Map([[obj1, '张三'],[obj2, '李四'],]);
语法
let 集合变量名 = new Map(指定格式的二维数组);
2、添加元素 set(key,value)
添加或修改某个键值对
let map = new Map();let obj1 = { name: '张三' }map.set(obj1, '张三');map.set('name', '李四');map.set(1, '王五');console.log(map);
3、获取元素值 get(key)
通过键名获取对应的键值
let map = new Map();let obj1 = { name: '张三' }map.set(obj1, '张三');map.set('name', '李四');map.set(1, '王五');console.log(map.get(obj1));//张三console.log(map.get('name'));//李四console.log(map.get(1));//王五
4、删除元素 delete(key)
通过键名删除对应的键值对,删除成功返回true,失败返回false
console.log(map.delete(obj1));//trueconsole.log(map);//Map(2) {'name' => '李四', 1 => '王五'}
5、查看元素数量 size
console.log(map.size);//2
6、获取所有键值对的键名 keys()
console.log(map.keys());
7、获取所有键值对的键值 values()
8、获取键值列表 entries()
返回的是一个map迭代器,可以用于遍历
console.log(map.entries());//MapIterator {'name' => '李四', 1 => '王五'}
9、遍历
for…of
ES6新增的用于遍历可迭代的对象的一种新的遍历方式。
let map = new Map();let obj1 = { name: '张三' }map.set(obj1, '张三');map.set('name', '李四');map.set(1, '王五');// ============= 1、直接获取,每个item是一个数组 =============for (let item of map) {console.log(item);}// [{name: '张三'},"张三"]// ['name', '李四']// [1, '王五']// // ============= 2、通过数组解构的方式遍历 =============for (let [key, value] of map) {console.log(key + " = " + value);}// [object Object] = 张三// name = 李四// 1 = 王五for (let key of map.keys()) {console.log(key);}// {name: '张三'}// name// 1// ============= 4、通过遍历值列表 =============for (let value of map.values()) {console.log(value);}// 张三// 李四// 王五// ============= 5、通过遍历键值列表 =============for (let [key, value] of map.entries()) {console.log(key + " = " + value);}// [object Object] = 张三// name = 李四// 1 = 王五
forEach
let map = new Map();let obj1 = { name: '张三' }map.set(obj1, '张三');map.set('name', '李四');map.set(1, '王五');map.forEach((value, key) => {console.log(key, value);});// {name: '张三'} '张三'// name 李四// 1 '王五'
10、清空 clear()
map集合变量名.clear();
11、合并
let first = new Map([[1, 'one'],[2, 'two'],[3, 'three'],]);let second = new Map([[1, 'uno'],[2, 'dos']]);// Map对象同数组进行合并时,如果有重复的键值,则后面的会覆盖前面的。let merged = new Map([...first, ...second, [1, 'eins']]);console.log(merged.get(1)); // einsconsole.log(merged.get(2)); // dosconsole.log(merged.get(3)); // three
12、转换
Map转Array
let map = new Map([[12, 34]]);//法1:console.log(Array.from(map));//法2:console.log([...map]);//法3:let arr=[];for(let key of map){arr.push(key);}console.log(arr);
应用
状态的对应储存值
let assS = {a:"待采购",b:"可领取",c:"使用中"}let assState = new Map()assState.set(assS.a,0)assState.set(assS.b,1)assState.set(assS.c,2)assS.a // "待采购" 需要用于界面显示时,用这个assState.get(assS.a) // 0 把这个状态实际表示的值,传给后端进行储存
