Map将NaN视为同一键,且+0与-0相等;其他值遵循SameValueZero规则,即字符串字面量与String对象不同、对象按引用区分、undefined/null/0/false等各自独立。

JavaScript中Map的键名使用严格全等(===)语义进行比较,但有一个关键例外:NaN被视为与自身相等——这是Map内部实现的特殊约定,不同于原生===对NaN的判定(NaN === NaN为false)。
Map的键比较不完全等价于===
虽然文档常描述Map“使用SameValueZero算法”比较键,但实际行为更准确地说是“SameValueZero的变体”,尤其在NaN处理上:
-
===中:NaN === NaN→false - Map中:
map.set(NaN, 'a'); map.get(NaN)→ 正确返回'a' - 这意味着Map内部对
NaN做了显式特判,将其统一视为同一键
哪些值会被Map认为是同一个键?
除NaN外,其他值仍遵循SameValueZero规则:
-
+0和-0被视为相等(map.set(+0, 1); map.get(-0)→1) - 字符串字面量与
String对象不同('abc'≠new String('abc')) - 对象即使内容相同,引用不同即为不同键(
{}和{}是两个键) -
undefined、null、0、false等各自独立,不发生类型转换
实际开发中的注意事项
利用这一特性可安全地用NaN作键,但需注意边界情况:
立即学习“Java免费学习笔记(深入)”;
- 不要依赖
NaN键做业务主逻辑,因其语义模糊(比如统计错误值时,多个NaN输入会覆盖而非累加) - 遍历
map.keys()时,NaN键会以NaN形式出现,但无法用===直接比对,应改用Number.isNaN()判断 - 若需区分
+0和-0,Map不适合——考虑用Object手动封装键或使用Array存储[键标识, 值]对
验证NaN键行为的小例子
可直接在控制台运行验证:
const m = new Map(); m.set(NaN, 'nan-value'); m.set(0, 'zero'); console.log(m.get(NaN)); // 'nan-value' console.log(m.has(NaN)); // true console.log(NaN === NaN); // false(对比用)
这个设计让Map在处理计算结果可能为NaN的场景(如数值聚合、坐标映射)时更健壮,也避免了开发者手动预处理NaN的麻烦。










