在 JavaScript 中,Set
的 add()
方法和数组的 push()
方法都可用于添加元素,但它们在数据结构、功能和行为上存在本质区别。以下是详细对比:
一、核心区别概览
特性 | Set.prototype.add() |
Array.prototype.push() |
---|---|---|
数据结构 | 无序唯一值集合(无索引) | 有序列表(有索引) |
重复元素处理 | 自动过滤重复值(基于 === ) |
允许添加重复值 |
返回值 | 返回 Set 本身(支持链式调用) | 返回新数组长度 |
元素顺序 | 按添加顺序排列(遍历时保持) | 按插入位置排序(索引决定顺序) |
性能(大数据量) | 插入/查找效率高(O(1) 时间复杂度) | 插入效率低(尾部 O(1),中间/头部 O(n)) |
访问方式 | 无索引,通过 has() 检查存在性 |
通过索引访问元素(如 arr[0] ) |
二、具体差异详解
1. 重复元素处理
Set.add():自动去重,确保元素唯一性。
const set = new Set(); set.add(1).add(1); // 第二次添加无效 console.log([...set]); // [1]
Array.push():允许重复元素。
const arr = []; arr.push(1, 1); console.log(arr); // [1, 1]
2. 返回值与链式调用
Set.add():返回 Set 本身,支持链式调用。
const set = new Set(); set.add(1).add(2).add(3); // 链式添加
Array.push():返回新数组长度。
const arr = []; const length = arr.push(1, 2); console.log(length); // 2
3. 元素顺序与访问
Set:无索引,遍历顺序由添加顺序决定。
const set = new Set(); set.add(3).add(1).add(2); console.log([...set]); // [3, 1, 2](按添加顺序)
Array:依赖索引,可随机访问。
const arr = []; arr.push(3, 1, 2); console.log(arr[1]); // 1(按索引访问)
4. 性能差异
Set:插入和查找元素的时间复杂度为 O(1),适合频繁检查元素存在性的场景。
// 检查元素是否存在 console.log(set.has(1)); // O(1)
Array:检查元素存在性需遍历数组(如
includes()
),时间复杂度为 O(n)。console.log(arr.includes(1)); // O(n)
三、应用场景对比
场景 | 推荐使用 Set | 推荐使用 Array |
---|---|---|
存储唯一值集合 | ✅ 自动去重 | ❌ 需手动检查重复 |
频繁检查元素存在性 | ✅ O(1) 时间复杂度 | ❌ O(n) 时间复杂度 |
需要按索引随机访问元素 | ❌ 无索引支持 | ✅ 索引访问高效 |
维护元素插入顺序 | ✅ 遍历时保持添加顺序 | ✅ 索引严格控制顺序 |
处理大数据量 | ✅ 插入/删除效率高 | ❌ 中间插入/删除性能较差 |
四、示例对比
1. 数组去重
// 使用 Set
const uniqueArray = [...new Set([1, 2, 2, 3])];
console.log(uniqueArray); // [1, 2, 3]
// 使用 Array(手动去重)
const arr = [1, 2, 2, 3];
const unique = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(unique); // [1, 2, 3](代码更复杂)
2. 检查元素存在性
// Set 更高效
const set = new Set([1, 2, 3]);
console.log(set.has(2)); // true(O(1))
// Array 需遍历
const arr = [1, 2, 3];
console.log(arr.includes(2)); // true(O(n))
3. 维护有序列表
// Array 更适合
const arr = [];
arr.push(3);
arr.push(1);
console.log(arr[0]); // 3(按索引访问)
// Set 无法通过索引访问
const set = new Set();
set.add(3).add(1);
// 需遍历获取元素,无直接索引访问方式
五、总结:如何选择?
使用 Set:
- 需要元素唯一性。
- 频繁检查元素存在性。
- 无需按索引访问,只需遍历。
使用 Array:
- 需要维护元素顺序(通过索引控制)。
- 允许重复元素。
- 需要随机访问或操作特定位置的元素(如
splice()
、map()
等)。
理解两者差异后,可根据具体需求灵活选择数据结构,提升代码效率和可读性。