ES6 中 Map 和 Set

ES6(ECMAScript 2015)引入了许多新的特性和数据结构,其中 MapSet 是两个非常重要的集合类型。它们为 JavaScript 提供了更加灵活、高效的方式来存储和操作数据。在这篇文章中,我们将深入探讨 MapSet 的特点、用法以及在实际场景中的应用。

目录

  1. 什么是 Map 和 Set
  2. Map 的特点
    1. 键值对存储
    2. 任意类型的键
    3. 键的顺序
  3. Set 的特点
    1. 唯一值
    2. 值的类型
    3. 值的顺序
  4. Map 和 Set 与传统对象和数组的对比
  5. Map 的常用操作
    1. 添加、删除和更新元素
    2. 查找元素
    3. 遍历 Map
    4. Map 的方法
  6. Set 的常用操作
    1. 添加、删除和清空元素
    2. 查找元素
    3. 遍历 Set
    4. Set 的方法
  7. Map 和 Set 的应用场景
    1. Map 的应用场景
    2. Set 的应用场景
  8. 性能对比:Map vs Object,Set vs Array
  9. 总结

什么是 Map 和 Set

在 JavaScript 中,MapSet 是两个新的集合类型,它们分别用于存储键值对数据和唯一值集合。

  • Map 是一个键值对的集合,每个键和值都有一一对应的关系。与传统的对象不同,Map 的键可以是任意类型(不仅仅是字符串或符号),并且它保留插入的顺序。
  • Set 是一个值的集合,集合中的每个值都是唯一的,不允许重复。Set 的元素也可以是任意类型,并且它保留元素的插入顺序。

Map 的特点

键值对存储

Map 允许存储键值对,类似于传统对象,但与对象相比,Map 提供了更多的优势和灵活性。

javascriptCopy Code
const map = new Map(); map.set('name', 'John'); map.set('age', 30); console.log(map.get('name')); // John console.log(map.get('age')); // 30

任意类型的键

在传统对象中,键必须是字符串或符号。而在 Map 中,键可以是任何类型,包括对象、数组和函数等。

javascriptCopy Code
const map = new Map(); const objKey = { id: 1 }; const arrKey = [1, 2, 3]; const fnKey = function() {}; map.set(objKey, 'Object Key'); map.set(arrKey, 'Array Key'); map.set(fnKey, 'Function Key'); console.log(map.get(objKey)); // Object Key console.log(map.get(arrKey)); // Array Key console.log(map.get(fnKey)); // Function Key

键的顺序

Map 保留插入键值对的顺序。无论我们如何操作 Map,它始终按插入的顺序存储和遍历键值对。

javascriptCopy Code
const map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); for (let [key, value] of map) { console.log(key, value); } // 输出: // a 1 // b 2 // c 3

Set 的特点

唯一值

Set 是一个集合,它的每个元素都是唯一的。插入重复的元素时,Set 会自动忽略重复的元素。

javascriptCopy Code
const set = new Set(); set.add(1); set.add(2); set.add(2); // 不会重复添加 set.add(3); console.log(set); // Set { 1, 2, 3 }

值的类型

Set 可以存储任意类型的值,包括原始类型和对象类型。

javascriptCopy Code
const set = new Set(); set.add(1); set.add('hello'); set.add([1, 2, 3]); console.log(set); // Set { 1, 'hello', [ 1, 2, 3 ] }

值的顺序

Set 也会保留插入值的顺序。你可以按照插入顺序遍历 Set 中的元素。

javascriptCopy Code
const set = new Set(); set.add('a'); set.add('b'); set.add('c'); for (let value of set) { console.log(value); } // 输出: // a // b // c

Map 和 Set 与传统对象和数组的对比

Map vs Object

  • 键的类型:对象的键只能是字符串或符号,而 Map 的键可以是任意类型。
  • 顺序Map 会按照插入的顺序遍历键值对,而对象的键是无序的(对于字符串键,顺序可能是插入顺序,但它并不保证)。
  • 性能:当涉及到频繁的键值对操作时,Map 的性能通常优于对象。
javascriptCopy Code
const obj = { name: 'Alice', age: 25 }; const map = new Map(); map.set('name', 'Alice').set('age', 25); // 遍历对象 for (let key in obj) { console.log(key, obj[key]); } // 遍历 Map for (let [key, value] of map) { console.log(key, value); }

Set vs Array

  • 唯一性Set 保证每个元素是唯一的,而 Array 可以包含重复的元素。
  • 查找效率Set 对于查找是否存在某个元素的性能优于 Array,尤其是在元素数量较大时。
  • 插入效率:在 Set 中,插入重复元素会被自动忽略,而在 Array 中,重复元素会继续添加。
javascriptCopy Code
const arr = [1, 2, 2, 3, 4, 4]; const set = new Set(arr); console.log(set); // Set { 1, 2, 3, 4 }

Map 的常用操作

添加、删除和更新元素

Map 提供了 setdeleteclear 方法来操作数据。

javascriptCopy Code
const map = new Map(); map.set('a', 1); map.set('b', 2); // 更新元素 map.set('a', 3); console.log(map.get('a')); // 3 // 删除元素 map.delete('b'); console.log(map.get('b')); // undefined // 清空所有元素 map.clear(); console.log(map.size); // 0

查找元素

Map 提供了 get 方法来获取值,has 方法来判断是否存在指定的键。

javascriptCopy Code
const map = new Map(); map.set('name', 'John'); map.set('age', 30); console.log(map.get('name')); // John console.log(map.has('age')); // true console.log(map.has('gender')); // false

遍历 Map

你可以使用 for...of 循环遍历 Map,或者使用 forEach 方法。

javascriptCopy Code
const map = new Map(); map.set('a', 1); map.set('b', 2); for (let [key, value] of map) { console.log(key, value); } // 输出: // a 1 // b 2 map.forEach((value, key) => { console.log(key, value); }); // 输出: // a 1 // b 2

Map 的方法

  • set(key, value):添加或更新键值对。
  • get(key):获取指定键的值。
  • has(key):判断 Map 是否包含某个键。
  • delete(key):删除指定键值对。
  • clear():删除所有键值对