JavaScript Map 和 Set 教程
Map 数据结构
Map 基本概念
Map 是一种键值对的集合,类似于对象(Object),但是它的键可以是任何数据类型(包括对象、函数等),而不仅限于字符串。Map 提供了一系列方法来操作这些键值对。
Map 的创建和基本操作
// 创建空 Map
const map = new Map();// 使用数组创建 Map
const map2 = new Map([['name', '张三'],['age', 25]
]);// 添加键值对
map.set('key1', 'value1');
map.set(true, 123);
map.set({x: 1}, 'object as key');// 获取值
console.log(map.get('key1')); // 'value1'// 检查键是否存在
console.log(map.has('key1')); // true// 删除键值对
map.delete('key1');// 获取 Map 大小
console.log(map.size);// 清空 Map
map.clear();
Map 的遍历方法
const map = new Map([['name', '张三'],['age', 25],['city', '北京']
]);// 遍历所有键值对
map.forEach((value, key) => {console.log(`${key}: ${value}`);
});// 获取所有键
for (let key of map.keys()) {console.log(key);
}// 获取所有值
for (let value of map.values()) {console.log(value);
}// 获取所有键值对
for (let [key, value] of map.entries()) {console.log(`${key}: ${value}`);
}
Map 与对象的区别
- 键的类型:Map 的键可以是任何类型,Object 的键只能是字符串或 Symbol
- 键的顺序:Map 会维护键值对的插入顺序,Object 不保证顺序
- Size:Map 可以直接获取 size 属性,Object 需要手动计算
- 迭代:Map 可直接迭代,Object 需要先获取键数组
Set 数据结构
Set 基本概念
Set 是一种值的集合,其中的值都是唯一的。它类似于数组,但成员的值都是唯一的,没有重复的值。
Set 的创建和基本操作
// 创建空 Set
const set = new Set();// 使用数组创建 Set
const set2 = new Set([1, 2, 3, 3, 4]); // 重复值会被自动去除// 添加值
set.add(1);
set.add('text');
set.add({x: 10});// 检查值是否存在
console.log(set.has(1)); // true// 删除值
set.delete(1);// 获取 Set 大小
console.log(set.size);// 清空 Set
set.clear();
Set 的遍历方法
const set = new Set(['A', 'B', 'C']);// forEach 遍历
set.forEach(value => {console.log(value);
});// for...of 遍历
for (let item of set) {console.log(item);
}// 获取所有值
for (let value of set.values()) {console.log(value);
}// 获取所有键(与值相同)
for (let key of set.keys()) {console.log(key);
}// 获取所有键值对(键和值相同)
for (let [key, value] of set.entries()) {console.log(key, value);
}
Set 的常用应用场景
- 数组去重
const array = [1, 2, 2, 3, 3, 4];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // [1, 2, 3, 4]
- 并集、交集和差集操作
const setA = new Set([1, 2, 3]);
const setB = new Set([2, 3, 4]);// 并集
const union = new Set([...setA, ...setB]);// 交集
const intersection = new Set([...setA].filter(x => setB.has(x)));// 差集
const difference = new Set([...setA].filter(x => !setB.has(x)));
性能考虑
Map 的性能优势
- 频繁增删键值对场景下,Map 比 Object 性能更好
- 键值对数量很大时,Map 的增删改查性能更优
Set 的性能优势
- 检查值是否存在的性能比数组好
- 处理大量数据去重时性能优于数组方法
最佳实践建议
- 选择使用 Map 的场景:
- 键需要是非字符串类型
- 需要频繁增删键值对
- 需要维护插入顺序
- 需要频繁获取大小
- 选择使用 Set 的场景:
- 需要存储唯一值集合
- 需要频繁检查值是否存在
- 需要数组去重
- 需要集合运算(并集、交集、差集)
- 注意事项:
- Map 和 Set 都不能序列化为 JSON
- WeakMap 和 WeakSet 适用于需要垃圾回收的场景
- 考虑浏览器兼容性,需要时使用 polyfill
