概念

是ES6新增的数据结构,用于存储映射关系。效果类似于对象,用于保存多个key:value形式的数据。在map中,我们称每个数据为一个键值对。map跟对象很很大不同
但是我们可能会想,在之前我们可以使用对象来存储映射关系,他们有什么区别呢?
事实上我们对象存储映射关系只能用字符串(ES6新增了Symbol )作为属性名( key ) ;
某些情况下我们可能希望通过其他类型作为key,比如对象,这个时候会自动将对象转成字符串来作为key ;

特点

  1. 对象保存键值对,并且能够记住键的原始插入顺序
  2. map集合中不能有重复的键名。
  3. 键值对,键可以是任意数值类型,而原生对象中的属性名只能是字符串

    和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、创建

  1. let newMap = new Map();

也可以创建时初始化里面的元素

  1. let newMap = new Map([
  2. [obj1, '张三'],
  3. [obj2, '李四'],
  4. ]);

语法

  1. let 集合变量名 = new Map(指定格式的二维数组);

2、添加元素 set(key,value)

添加或修改某个键值对

  1. let map = new Map();
  2. let obj1 = { name: '张三' }
  3. map.set(obj1, '张三');
  4. map.set('name', '李四');
  5. map.set(1, '王五');
  6. console.log(map);

image.png

3、获取元素值 get(key)

通过键名获取对应的键值

  1. let map = new Map();
  2. let obj1 = { name: '张三' }
  3. map.set(obj1, '张三');
  4. map.set('name', '李四');
  5. map.set(1, '王五');
  6. console.log(map.get(obj1));//张三
  7. console.log(map.get('name'));//李四
  8. console.log(map.get(1));//王五

4、删除元素 delete(key)

通过键名删除对应的键值对,删除成功返回true,失败返回false

  1. console.log(map.delete(obj1));//true
  2. console.log(map);//Map(2) {'name' => '李四', 1 => '王五'}

5、查看元素数量 size

  1. console.log(map.size);//2

6、获取所有键值对的键名 keys()

  1. console.log(map.keys());

返回的是一个map迭代器,可以用于遍历
image.png

7、获取所有键值对的键值 values()

返回的是一个map迭代器,可以用于遍历
image.png

8、获取键值列表 entries()

返回的是一个map迭代器,可以用于遍历

  1. console.log(map.entries());//MapIterator {'name' => '李四', 1 => '王五'}

9、遍历

得到的都是数组,返回 [ 键 , 值 ]

for…of

ES6新增的用于遍历可迭代的对象的一种新的遍历方式。

  1. let map = new Map();
  2. let obj1 = { name: '张三' }
  3. map.set(obj1, '张三');
  4. map.set('name', '李四');
  5. map.set(1, '王五');
  6. // ============= 1、直接获取,每个item是一个数组 =============
  7. for (let item of map) {
  8. console.log(item);
  9. }
  10. // [{name: '张三'},"张三"]
  11. // ['name', '李四']
  12. // [1, '王五']
  13. // // ============= 2、通过数组解构的方式遍历 =============
  14. for (let [key, value] of map) {
  15. console.log(key + " = " + value);
  16. }
  17. // [object Object] = 张三
  18. // name = 李四
  19. // 1 = 王五
  20. for (let key of map.keys()) {
  21. console.log(key);
  22. }
  23. // {name: '张三'}
  24. // name
  25. // 1
  26. // ============= 4、通过遍历值列表 =============
  27. for (let value of map.values()) {
  28. console.log(value);
  29. }
  30. // 张三
  31. // 李四
  32. // 王五
  33. // ============= 5、通过遍历键值列表 =============
  34. for (let [key, value] of map.entries()) {
  35. console.log(key + " = " + value);
  36. }
  37. // [object Object] = 张三
  38. // name = 李四
  39. // 1 = 王五

forEach

  1. let map = new Map();
  2. let obj1 = { name: '张三' }
  3. map.set(obj1, '张三');
  4. map.set('name', '李四');
  5. map.set(1, '王五');
  6. map.forEach((value, key) => {
  7. console.log(key, value);
  8. });
  9. // {name: '张三'} '张三'
  10. // name 李四
  11. // 1 '王五'

10、清空 clear()

  1. map集合变量名.clear();

11、合并

  1. let first = new Map([
  2. [1, 'one'],
  3. [2, 'two'],
  4. [3, 'three'],
  5. ]);
  6. let second = new Map([
  7. [1, 'uno'],
  8. [2, 'dos']
  9. ]);
  10. // Map对象同数组进行合并时,如果有重复的键值,则后面的会覆盖前面的。
  11. let merged = new Map([...first, ...second, [1, 'eins']]);
  12. console.log(merged.get(1)); // eins
  13. console.log(merged.get(2)); // dos
  14. console.log(merged.get(3)); // three

12、转换

Map转Array

  1. let map = new Map([[12, 34]]);
  2. //法1:
  3. console.log(Array.from(map));
  4. //法2:
  5. console.log([...map]);
  6. //法3:
  7. let arr=[];
  8. for(let key of map){
  9. arr.push(key);
  10. }
  11. console.log(arr);

应用

状态的对应储存值

  1. let assS = {a:"待采购",b:"可领取",c:"使用中"}
  2. let assState = new Map()
  3. assState.set(assS.a,0)
  4. assState.set(assS.b,1)
  5. assState.set(assS.c,2)
  6. assS.a // "待采购" 需要用于界面显示时,用这个
  7. assState.get(assS.a) // 0 把这个状态实际表示的值,传给后端进行储存