Set 是 ES6 新增的集合数据结构,也是前端数组去重最优雅、最高频的解决方案。面试常问:Set 的特性、去重原理、特殊边界情况,本文一次性吃透。
读音:Set /set/
一、什么是 Set?(面试标准答案)
Set 是 ES6 提供的无序、不重复 的集合数据结构,允许存储任意类型的数据,核心特性是自动剔除重复元素。
二、Set 四大核心特点
1. 元素唯一,天然去重
Set 中不允许存在重复值,自动过滤重复元素,这是它最核心的能力,也是实现数组去重的底层原理。
2. 有序遍历(按插入顺序)
早期集合结构无序,ES6 规范明确:Set 会保留元素插入顺序,遍历、转换数组时都会遵循存入的先后顺序。
3. 特殊的相等判断规则(高频坑点)
Set 去重底层基于严格相等 === 判断,但做了单独兼容处理:
-
常规判断:遵循
===规则 -
特殊处理:Set 中 NaN === NaN (普通 JS 中
NaN !== NaN),可以实现 NaN 去重 -
弊端:无法去重引用类型(对象、数组),不同引用地址的空对象/空数组会被判定为不同值
4. 存储类型不限
可以存储基本类型(数字、字符串、NaN 等)和引用类型(对象、数组、函数),适配性极强。
三、Set 实现数组去重(最简经典写法)
1. 核心语法
const newArr = [...new Set(arr)]
2. 完整实战示例
// 包含重复值、NaN 的数组 const arr = [1, 2, 2, 3, 3, NaN, NaN, 4]; // Set 去重 + 扩展运算符转数组 const res = [...new Set(arr)]; console.log(res); // [1, 2, 3, NaN, 4] 成功去重,NaN 也被过滤
3. 原理拆解
-
new Set(arr):将数组转为 Set 集合,自动剔除所有重复基本类型元素 -
[...]扩展运算符:将 Set 可迭代对象,重新展开转为全新数组
四、适用范围 & 局限性(面试重点)
✅ 适合:基本类型数组去重
数字、字符串、undefined、NaN、null 均可完美去重。
❌ 不适合:对象/数组等引用类型数组去重
引用类型对比的是内存地址,内容相同但地址不同,Set 判定为不同值,无法去重。
const arr = [{name:'张三'}, {name:'张三'}]; const res = [...new Set(arr)]; console.log(res); // 两个对象都保留,无法去重
五、Set 常用基础 API(拓展)
const s = new Set(); s.add(1); // 添加元素 s.delete(1); // 删除指定元素 s.has(1); // 判断是否存在,返回布尔值 s.size; // 获取元素个数(类似数组 length) s.clear(); // 清空所有元素