ES6(ECMAScript 2015)引入了Set和Map两种新数据结构,为JavaScript开发带来了更高效的数据处理方案。
它们有效解决了传统数组和对象在处理唯一值及复杂键值对时的局限性,展现出显著优势。
今天我们系统性地探讨Set与Map,涵盖核心概念、关键特性、使用方法以及实际应用场景。
一、Set数据结
它类似于数组,但成员的值都是唯一的,没有重复值。
这一特性使其在需要去重、判断存在性等场景中表现尤为出色。
创建Set :通过new Set()构造函数创建,可接收一个可迭代对象(如数组、字符串)作为初始数据。
javascript
// 空Set
const emptySet = new Set();
// 从数组创建(自动去重)
const setFromArray = new Set([1, 2, 3, 3, 4, 5]);
console.log(setFromArray .size); // 输出:5(重复的3被移除)
核心属性与方法
size: 用于获取集合中成员的数量(类似数组的length)
**add(value):**添加成员,返回Set本身(可链式调用)。
**delete(value):**删除指定成员,返回布尔值表示是否删除成功。
**has(value):**判断是否包含指定成员,返回布尔值。
**clear():**清空所有成员,无返回值。
需要注意Set的值比较规则 :与===类似,但有一个例外------NaN被视为与自身相等(而===中NaN !== NaN)。
javascript
const specialSet = new Set([NaN, NaN, 1, '1']);
console.log(specialSet.size); // 输出:3(两个NaN被视为重复,1与'1'是不同值)
典型应用场景
1.数组去重:利用Set的唯一性,配合扩展运算符快速去重。在各种业务场景中用于去除重复数据。
javascript
// 基本数组去重
const arr = [1, 2, 3, 2, 1, 4];
const uniqueArr = [...new Set(arr)]; // [1, 2, 3, 4]
// 对象数组去重(通过 JSON.stringify 和 JSON.parse)
const objArr = [{id: 1, name: '张三'}, {id: 2, name: '李四'}, {id: 1, name: '张三'}];
const uniqueObjArr = Array.from(new Set(objArr.map(x => JSON.stringify(x)))).map(x => JSON.parse(x));
2.组合数据:合并多个数组并自动去重,实现交集、并集、差集等数学集合操作。
javascript
const setA = newSet([1, 2, 3]);
const setB = newSet([2, 3, 4]);
// 并集:A∪B
const union = newSet([...setA, ...setB]); // {1,2,3,4}
// 交集:A∩B
const intersection = newSet([...setA].filter(x => setB.has(x))); // {2,3}
// 差集:A-B
const difference = newSet([...setA].filter(x => !setB.has(x))); // {1}
3.成员检查:快速检查一个值是否存在于集合中。
4.存储唯一标识:存储不允许重复的唯一标识符。如用户ID、DOM节点等需要唯一存储的数据。
二、Map数据结构
Map 是 ES6 引入的另一种新的数据结构,Map是一种有序的键值对集合,它类似于对象,但键的范围不限于字符串,各种类型的值(包括对象)都可以当作键。键的类型很灵活。
创建Map :通过new Map()构造函数创建,可接收一个二维数组 (每个子数组为[key, value])作为初始数据。
javascript
// 空Map
const emptyMap = new Map();
// 从二维数组创建
const userMap = new Map([
['name', 'Alice'],
[18, 'age'], // 键可以是数字
[() => {}, 'method'] // 键可以是函数
]);
console.log(userMap.size); // 输出:3
核心属性与方法
size:size用于获取键值对的数量。
**set(key, value):**添加键值对,返回Map本身(可链式调用)。
get(key): 获取指定键对应的值,若不存在返回undefined。
**delete(key):**删除指定键值对,返回布尔值表示是否删除成功。
**has(key):**判断是否包含指定键,返回布尔值。
**clear():**清空所有键值对,无返回值。
典型应用场景
**1. 高效查找:**通过键快速查找对应的值,提高数据处理效率
**2. 复杂键映射:**使用对象、函数等作为键进行数据映射
**3. 数据去重:**根据指定键去重对象数组
**4. 缓存实现:**临时存储键值对数据,提高访问速度
javascript
// 用DOM元素作为键存储数据(避免污染DOM属性)
const domMap = new Map();
const button = document.querySelector('button');
domMap.set(button, { clickCount: 0 });
// 点击时更新数据
button.addEventListener('click', () => {
const data = domMap.get(button);
data.clickCount++;
console.log(`点击次数:${data.clickCount}`);
});
如何选择Set与Map?
Set:适用于需要存储唯一值的场景,如数组去重、成员检查等。
Map:适用于需要键值对映射的场景,如高效查找、复杂键映射,需要保持顺序或频繁修改时。
Set 和 Map 是 ES6 引入的两种强大的数据结构,它们在处理特定类型的数据时提供了更高效、更简洁的方式。
在实际项目开发中,合理使用 Set 和 Map 可以提高代码的可读性、性能和可维护性。
掌握这两种数据结构的使用方法和最佳实践,将有助于你编写更加高效、优雅的 JavaScript 代码。