ES6+知识点汇总(5)— Map

72 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情

十二、Map

12-1、Map是什么

Map和对象都是键值对的集合,但是Map和对象有如下区别:

  • 对象一般用字符串当作键
  • 而基本数据类型(数字、字符串、布尔值、undefined、null)与引用数据类型(对象、数组、函数、Set、Map等)都可以作为Map的键
const m = new Map();
m.set('name', 'zs');
m.set(true, 'true');
m.set({}, 'object');
m.set(new Set([1, 2]), 'set');
m.set(undefined, 'undefined');
console.log(m);

12-2、Map实例的方法和属性

12-2-1、Map实例的方法

12-2-1-1、set()

用于向Map实例中添加成员

  • 如果添加的新的成员的key已经存在,那么会覆盖前面相同key的成员
  • set方法也支持链式调用
const m = new Map();
// 使用 set 添加的新成员,键如果已经存在,后添加的键值对覆盖已有的
m.set('age', 18).set(true, 'true').set('age', 20);
console.log(m); // Map(2) {'age' => 20, true => 'true'}
12-2-1-2、get()

用于获取Map实例中指定值

  • 如果获取的值不存在则返回undefined
const m = new Map();
m.set('age', 18).set(true, '1').set('age', 20);
console.log(m);
console.log(m.get('age')); // 18
// get 获取不存在的成员,返回 undefined
console.log(m.get('true')); // undefined
console.log(m.get(true)); // 1
12-2-1-3、has()

用于判断Map中有无指定键

const m = new Map();
m.set('age', 18).set(true, '1').set('age', 20);

console.log(m.has('age')); // true
console.log(m.has('true')); // false
console.log(m.has(true)); // true
12-2-1-4、delete()

用于删除指定键的键值对

  • 如果删除的内容不存在,则什么都不会发生,也不会报错
const m = new Map();
m.set('age', 18).set(true, '1').set('age', 20);

m.delete('age');
m.delete('name');
12-2-1-5、clear()

清空Map

const m = new Map();
m.set('age', 18).set(true, '1').set('age', 20);
m.clear();

12-2-2、Map实例的属性

Map实例的属性:size

  • 用于获取Map中成员个数
const m = new Map();
m.set('age', 18).set(true, '1').set('age', 20);
console.log(m.size); // 2

12-3、Map构造函数的参数

在我们实例化Map时,同样也可以为Map构造函数传递参数,我们可以传递如下内容:

  • 数组(二维数组)
  • Set、Map等

12-3-1、传递数组

传递的数组必须是二维数组,传递一维数组会报错:因为要体现出键值对的关系,而一维数组无法体现!

     console.log(
        new Map([
          ['name', 'zs'],
          ['age', 18]
        ])
      );

12-3-2、传递Set、Map

我们也可以向Map的构造函数中传递Set、Map

  • 要注意的是如果是传递Set,该Set也要体现出键值对,即是一个二维数组
  • 传递Map相当于复制出了一个新的Map
// Set 中也必须体现出键和值
const s = new Set([
  ['name', 'zs'],
  ['age', 18]
]);
console.log(new Map(s));
console.log(s);

// Map
// 复制了一个新的 Map
const m1 = new Map([
  ['name', 'zs'],
  ['age', 18]
]);
console.log(m1);
const m2 = new Map(m1);
console.log(m2, m2 === m1); // false

12-4、Map注意事项

12-4-1、Map判断键是否相等的方式

基本遵循严格相等,但是NaN比较特殊,NaN不等于本身,但是作为Map键时,如果存在了NaN的键,那么后为NaN键的键值对会覆盖前面的:

const m = new Map();
m.set(NaN, 1).set(NaN, 2);
console.log(m); // {NaN => 2}

12-4-2、什么时候使用Map

我们知道,Map与对象本质上都是键值对的集合,那么什么时候使用Map什么时候使用对象呢?

  • 如果我们只想单纯表示键值对的结果,或者我们想用除了字符串以外的数据类型作为键,那么使用Map
  • 如果我们想使用Map提供的方法以及想直接forEach来遍历也适合使用Map
  • 对象适合表示一个现实中的实体

12-5、Map的应用

比如要给3个P标签设置不同的背景、字体颜色、字体大小

思路:

  • 此时我们可以获取这3个P标签,以P标签作为key
  • P标签对应的背景、字体颜色、字体大小我们可以放在一个对象中去保存,用于作为P标签对应的值
  • 将三个P标签与其对应的值一一映射好放入一个Map中
  • 遍历该Map,依次取出P标签与其对应的值,为P标签设置上相应的属性即可

代码示例如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>Map 的应用</title>
</head>

<body>
  <p>1</p>
  <p>2</p>
  <p>3</p>

  <script>
    const [p1, p2, p3] = document.querySelectorAll('p');

    const m = new Map([
      [
        p1,
        {
          color: 'red',
          backgroundColor: 'yellow',
          fontSize: '20px'
        }
      ],
      [
        p2,
        {
          color: 'green',
          backgroundColor: 'pink',
          fontSize: '30px'
        }
      ],
      [
        p3,
        {
          color: 'blue',
          backgroundColor: 'orange',
          fontSize: '40px'
        }
      ]
    ]);

    m.forEach((propObj, elem) => {
      for (const p in propObj) {
        elem.style[p] = propObj[p];
      }
    });
  </script>
</body>

</html>