javascript中set对原始类型去重基于严格相等(===),但nan视为相同、0与-0相等;包装对象不自动解包,需显式转换;空字符串、0、false等互不相等。

JavaScript中Set对原始类型(如字符串、数字、布尔值、undefined、null、Symbol、BigInt)的去重,是基于严格相等(===)比较规则进行的,不涉及引用或包装对象的隐式转换。
原始类型的值比较直接且确定
Set内部判断两个原始值是否重复时,完全依赖JavaScript的严格相等算法:
-
数字:
0和-0被视为相等(ES2015规定),所以new Set([0, -0])只存一个0;NaN === NaN为false,但Set中NaN被视为相同值,即new Set([NaN, NaN])长度为1(这是Set的特殊约定,与===不同); -
字符串:按字符序列逐位比较,
"1"和1类型不同,不会去重; -
布尔值、undefined、null:各自独立,
true、false、undefined、null互不相等,也与其他类型不相等; -
Symbol:每个
Symbol()调用都生成唯一值,即使描述相同(如Symbol('a')和Symbol('a'))也不相等; -
BigInt:
1n === 1为false,且1n === 1n为true,能正确区分和去重。
注意包装对象不会自动解包
如果你传入的是原始类型的包装对象(如new String("a")、new Number(42)),Set不会将其当作原始值处理:
-
new Set(["a", new String("a")])长度为2,因为字符串字面量和String实例是不同类型(前者是primitive,后者是object); - 同理,
new Set([42, new Number(42)])也会保留两个元素; - 若需统一,应显式调用
.valueOf()或使用展开+String()/Number()转换后再构造Set。
常见易错点提醒
实际使用中容易混淆的几个情况:
-
0、-0、+0在Set中视为同一值; -
NaN虽然不等于自身,但在Set中只保留第一个出现的NaN; - 空字符串
""、数字0、布尔false、null、undefined两两都不相等,不会相互去重; - 带前导零或大小写的字符串(如
"01"vs"1"、"A"vs"a")严格区分,不会模糊匹配。
理解这些细节后,Set对原始类型的去重行为就非常可靠——它不猜测意图,只忠实执行语言规范定义的相等逻辑。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











