Set 的 has 方法是判断元素是否存在的最直接、最高效方式,时间复杂度 O(1),基于哈希表查找,支持 SameValueZero 相等性(NaN 与自身相等),原始值按值比较、对象按引用比较,不支持索引访问。

Set 的 has 方法是判断元素是否存在的最直接、最高效的方式,时间复杂度为 O(1)。 它不遍历整个集合,而是利用内部哈希表机制直接查找,比用数组的 includes 或 indexOf 快得多,尤其在大数据量时优势明显。
has 方法的基本用法
调用 set.has(value),传入要检查的值,返回布尔值:
- 如果值存在,返回 true;
- 不存在则返回 false。
- 注意:Set 判断相等使用的是 SameValueZero 算法,和 === 类似,但 NaN === NaN 为 false,而 Set 认为 NaN 等于 NaN(即 set.has(NaN) 在 NaN 已存在时会返回 true)
- 原始值(如字符串、数字、布尔值)按值比较;对象按引用比较,即使两个对象内容相同,只要不是同一个引用,has 就返回 false
常见使用场景示例
比如去重后快速查重、权限校验、状态标记等:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 用户权限检查:const permissions = new Set(['read', 'write', 'delete']); permissions.has('admin') // false
- 避免重复操作:if (!processedIds.has(id)) { process(id); processedIds.add(id); }
- 过滤已处理数据:const seen = new Set(); data.filter(item => !seen.has(item) && seen.add(item))
和数组 includes 对比的性能差异
Set.has 是常数时间查找;数组 includes 需要逐项遍历,最坏 O(n):
- 10 万个元素的 Set,has 查找几乎无延迟
- 同样规模的数组,includes 可能需要遍历数万次才能确认不存在
- 高频判断场景(如渲染循环、事件监听)强烈建议用 Set + has 替代数组查找
注意事项与易错点
- Set 不支持通过索引访问,set[0] 是 undefined,必须用 has、add、delete 等方法操作
- 对象作为键时,每次 new Object() 都是新引用:const s = new Set(); s.add({}); s.has({}) // false
- 如果需按内容查对象,应先序列化(如 JSON.stringify)再存入 Set,或改用 Map + 自定义 key 生成逻辑

















