Set主要特性
- 元素唯一性:Set 数据结构通过内部算法确保每个元素的唯一性。当向 Set 中添加一个已存在的元素时,它不会被再次添加。例如:
const set = new Set();
set.add(1);
set.add(1);
console.log(set.size); // 输出 1
- 可迭代性:Set 实现了迭代器接口,所以可以使用
for...of
循环或展开运算符(...
)来遍历其中的元素。例如:
const set = new Set([1, 2, 3]);
for (const value of set) {
console.log(value);
}
// 输出 1 2 3
const newArray = [...set];
console.log(newArray); // [1, 2, 3]
- 类型无关性:Set 可以存储任何类型的元素,包括对象、函数等,只要它们在
SameValueZero
比较下是唯一的。例如:
const set = new Set();
set.add({});
set.add(() => {});
Map主要特性
- 键类型多样性:普通对象的键只能是字符串或 Symbol 类型,而 Map 的键可以是任意类型。例如:
const map = new Map();
const obj = {};
map.set(obj, 'value associated with obj');
console.log(map.get(obj)); // 'value associated with obj'
- 顺序性:Map 记住键值对的插入顺序,而普通对象的属性顺序是不可预测的(在 ES6 之前)。例如:
const map = new Map();
map.set('a', 1);
map.set('b', 2);
const entries = Array.from(map.entries());
console.log(entries); // [['a', 1], ['b', 2]]
- 直接获取大小:Map 有
size
属性可以直接获取其键值对的数量,而普通对象需要手动计算。例如:
const map = new Map();
map.set('a', 1);
console.log(map.size); // 1
实际项目开发场景
- Set的使用场景:
- 去重:在处理数组去重时非常方便。例如,后端返回一个可能包含重复数据的数组,前端需要展示不重复的数据。
const duplicateArray = [1, 2, 2, 3, 3, 3];
const uniqueArray = [...new Set(duplicateArray)];
console.log(uniqueArray); // [1, 2, 3]
- **判断元素是否存在**:比在数组中使用 `indexOf` 或 `includes` 更高效,特别是当数据量较大时。例如,判断用户 ID 是否在已登录用户集合中。
const userIds = new Set([1, 2, 3]);
console.log(userIds.has(2)); // true
- Map的使用场景:
- 缓存数据:可以将函数的参数作为键,函数执行结果作为值存储在 Map 中,下次相同参数调用时直接从 Map 中获取结果,提高性能。例如,一个计算复杂的函数:
const cache = new Map();
function complexCalculation(a, b) {
const key = `${a}-${b}`;
if (cache.has(key)) {
return cache.get(key);
}
const result = a + b;
cache.set(key, result);
return result;
}
- **存储关联数据**:当需要存储具有某种关联关系的数据,且键的类型不是字符串时,Map 很适用。比如在游戏开发中,将游戏角色对象作为键,对应的属性信息作为值存储。
const character = {};
const characterStats = new Map();
characterStats.set(character, { health: 100, strength: 10 });