Map支持任意类型作键(对象、函数、Symbol、null、NaN等),因内部用SameValueZero算法比较键(===但NaN相等),而Object键仅限字符串/Symbol且会隐式转为字符串。

JavaScript 中的 Map 允许使用任意数据类型(包括对象、函数、Symbol、null、NaN 甚至其他 Map)作为键,这正是它区别于普通对象(Object)的核心优势——普通对象的键只能是字符串或 Symbol。
为什么普通对象不能真正支持任意类型作键
看似可以写 obj[{}],但实际会被自动转为字符串 "[object Object]",导致不同对象被当作同一个键。而 Map 内部使用严格相等(===)判断键是否相同,不进行类型转换,因此能准确区分不同引用或值。
Map 支持的常见键类型及用法示例
-
对象作键:每个对象实例都是独立键
const map = new Map();
const key1 = { id: 1 };
const key2 = { id: 1 };
map.set(key1, 'user A');
map.set(key2, 'user B');
console.log(map.size); // 2 —— 不会覆盖 -
函数作键:适合缓存函数执行结果或绑定元信息
const fn = () => {};
map.set(fn, { lastCalled: Date.now() }); -
Symbol 作键:天然唯一,避免属性名冲突
const sym = Symbol('meta');
map.set(sym, { hidden: true }); -
NaN 作键:普通对象中
obj[NaN] = 1实际等价于obj['NaN'] = 1,而 Map 中map.set(NaN, 'not a number')是有效的,且map.get(NaN)能正确返回值(Map 规定 NaN 键之间互相相等)。
注意 Map 的键比较逻辑
Map 使用“SameValueZero”算法比较键(类似 ===,但认为 NaN === NaN 为 true)。这意味着:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 两个不同的空对象
{}是不同键; - 两个相同的数组引用
[1,2]是同一键,但字面量[1,2]和[1,2]是不同键; -
0和-0在 Map 中被视为不同键(SameValueZero 认为它们不相等); -
undefined、null、布尔值、数字、字符串均可直接作键,无隐式转换。
实用技巧:用 WeakMap 存储私有数据(仅支持对象键)
如果只希望以对象为键,并且希望键对象被垃圾回收时自动清理对应值,可用 WeakMap:
立即学习“Java免费学习笔记(深入)”;
- WeakMap 的键必须是对象(不支持原始值);
- 键是弱引用,不影响垃圾回收;
- 常用于扩展对象而不污染其属性,例如存储 DOM 元素的状态:
const button = document.querySelector('button');
elementData.set(button, { clicked: 0 });
button.addEventListener('click', () => {
elementData.set(button, { clicked: elementData.get(button).clicked + 1 });
});

















