在 JavaScript 中,Set 是 ES6(ECMAScript 2015)引入的一种新的数据结构,用于存储唯一的值(不允许重复)。它类似于数组,但成员的值都是唯一的,没有重复项。
一、基本特性
- 值的唯一性:Set 中的每个值都是唯一的,无论添加多少次相同的值,最终只会保留一个。
- 存储类型:可以存储任何类型的值(原始值或对象引用)。
- 迭代性:Set 是可迭代的(iterable),可以使用 for...of 循环遍历。
- 无序性:ES6 规范中 Set 不保证元素的顺序(但现代浏览器通常按插入顺序保存)。
二、创建 Set
可以通过 new Set() 构造函数创建 Set,参数可以是一个可迭代对象(如数组):
// 1. 创建空 Set
const emptySet = new Set();
// 2. 从数组创建(自动去重)
const numberSet = new Set([1, 2, 3, 3, 4]);
console.log(numberSet); // Set(4) {1, 2, 3, 4}
// 3. 从字符串创建(字符串是可迭代的)
const strSet = new Set('hello');
console.log(strSet); // Set(4) {'h', 'e', 'l', 'o'}(去重了重复的 'l')
三、常用属性和方法
1. 属性
- size:返回 Set 中元素的数量(类似数组的 length)。
const mySet = new Set([1, 2, 3]);
console.log(mySet.size); // 3
2. 方法
| 方法名 | 说明 |
|---|---|
| add(value) | 向 Set 中添加一个值,返回 Set 本身(可链式调用)。 |
| delete(value) | 删除 Set 中的某个值,返回布尔值(成功删除为 true,否则 false)。 |
| has(value) | 判断 Set 中是否存在某个值,返回布尔值。 |
| clear() | 清空 Set 中的所有值,无返回值。 |
| keys() | 返回一个迭代器,包含 Set 中所有元素的值(与 values() 相同)。 |
| values() | 返回一个迭代器,包含 Set 中所有元素的值。 |
| entries() | 返回一个迭代器,包含 Set 中所有元素的 [value, value] 数组(因为 Set 没有键,键和值相同)。 |
| forEach(callback) | 遍历 Set 中的元素,类似数组的 forEach。 |
四、使用示例
1. 添加和删除元素
const fruits = new Set();
// 添加元素(可链式调用)
fruits.add('apple').add('banana').add('orange');
console.log(fruits); // Set(3) {'apple', 'banana', 'orange'}
// 判断是否存在
console.log(fruits.has('banana')); // true
console.log(fruits.has('grape')); // false
// 删除元素
fruits.delete('banana');
console.log(fruits); // Set(2) {'apple', 'orange'}
// 清空所有元素
fruits.clear();
console.log(fruits); // Set(0) {}
2. 遍历 Set
const colors = new Set(['red', 'green', 'blue']);
// 1. for...of 遍历(直接遍历值)
for (const color of colors) {
console.log(color); // red, green, blue
}
// 2. 使用 forEach
colors.forEach((value, key, set) => {
// 注意:Set 中 key 和 value 相同
console.log(`key: ${key}, value: ${value}`);
// 输出:key: red, value: red;key: green, value: green;key: blue, value: blue
});
// 3. 使用 values() 迭代器
const values = colors.values();
console.log(values.next().value); // red
console.log(values.next().value); // green
3. 应用场景
- 数组去重:利用 Set 的唯一性快速去重。
const arr = [1, 2, 2, 3, 3, 3];
const uniqueArr = [...new Set(arr)]; // [1, 2, 3]
- 判断元素是否存在:Set 的 has 方法比数组的 indexOf 或 includes 效率更高(时间复杂度为 O (1))。
- 存储唯一值集合:如存储用户 ID、标签等需要去重的数据。
五、注意事项
- 值的比较规则:
const set = new Set();
set.add(NaN);
set.add(NaN); // 不会重复添加
console.log(set.size); // 1
set.add(+0);
set.add(-0); // 不会重复添加
console.log(set.size); // 2(加上之前的 NaN)
-
- Set 使用 SameValueZero 算法判断两个值是否相等,与 === 类似,但有区别:
-
-
- NaN 被视为与自身相等(NaN === NaN 为 false,但 Set 中 NaN 只会存一个)。
-
-
-
- +0 和 -0 被视为相等。
-
- 对象引用的唯一性:
const obj1 = { name: 'a' };
const obj2 = { name: 'a' };
const objSet = new Set([obj1, obj2]);
console.log(objSet.size); // 2(obj1 和 obj2 是不同的引用)
-
- Set 中存储的对象是引用类型,两个不同的对象即使内容相同,也会被视为不同的值。
总结
Set 是 JavaScript 中用于存储唯一值的高效数据结构,适用于去重、快速查找等场景。它的 API 简洁易用,且迭代方式灵活,是处理唯一值集合的理想选择。