JavaScript原始类型在Map和Set中按值严格比较(===),NaN和0/-0有特殊处理;Symbol每次新建唯一,BigInt与数字不等;包装对象与原始值视为不同项。

JavaScript原始类型(如字符串、数字、布尔值、null、undefined、Symbol、BigInt)在 Map 和 Set 中作为键或成员时,表现稳定且符合预期——它们按值比较,而非引用。这是与对象类型的关键区别。
Map 中原始类型键名是安全且可预测的
Map 使用严格相等(===)判断键是否重复,对原始类型来说,这意味着相同字面量值就是同一个键:
-
map.set("a", 1)和map.set("a", 2)会覆盖,因为两个字符串"a"值相等且类型相同 -
map.set(0, "zero")和map.set(-0, "minus-zero")实际指向同一个键(0 === -0为true) -
map.set(NaN, "nan")是合法的;虽然NaN !== NaN,但Map内部对NaN做了特殊处理,保证它能被正确检索和复用 -
Symbol("a")每次调用都生成新值,因此map.set(Symbol("a"), 1)和map.set(Symbol("a"), 2)是两个不同键
Set 中原始类型成员去重逻辑清晰
Set 同样基于值的严格相等做唯一性判断:
-
new Set([1, 1, "1", true])得到{1, "1", true}(共 3 个元素),因为1 !== "1",1 !== true -
new Set([0, -0])只含一个元素:0(0 === -0) -
new Set([NaN, NaN])也只含一个NaN(Set对NaN同样有特殊等价处理) -
undefined和null各自独立存在,互不冲突,也与其他值不相等
注意隐式转换陷阱:不要混用包装对象
原始值和其包装对象(如 new String("a")、new Number(42))不是同一类型,在 Map 或 Set 中视为不同项:
立即学习“Java免费学习笔记(深入)”;
-
map.set("a", 1)和map.set(new String("a"), 2)是两个键:字符串字面量 ≠ 字符串对象 -
new Set(["a", new String("a")])包含两个成员 - 除非显式调用
.valueOf()或String(x)等转换,否则包装对象不会自动降为原始值参与比较
BigInt 与 Symbol 的行为需单独留意
这两类原始类型在比较时更“严格”,但也更可靠:
-
BigInt支持任意精度整数,1n === 1为false(类型不同),1n === 1n为true - 每个
Symbol都是唯一值,即使描述相同:Symbol("x") !== Symbol("x") -
Symbol.for("x")则共享全局注册表,两次调用返回同一 Symbol,可用于跨模块键共享










