map支持任意类型键,基于===判断相等;对象/函数作键需复用同一引用;weakmap仅支持对象键且自动垃圾回收。

JavaScript 的 Map 对象天然支持任意类型作为键,包括对象、函数、甚至其他 Map 或 Set,这和普通对象(Object)只接受字符串或 Symbol 作键有本质区别。关键在于:Map 用的是「严格相等(===)」判断键是否重复,而不是字符串转换。
对象作键:引用相等才视为同一键
当你用一个对象字面量 {a: 1} 作为键,每次新建都是不同引用,会被当作新键处理:
❌ 错误示范(看似相同,实为不同键):
const map = new Map();
map.set({a: 1}, 'value1');
map.set({a: 1}, 'value2'); // 不覆盖,map.size === 2
console.log(map.get({a: 1})); // undefined —— 因为是第三个新对象
✅ 正确做法:复用同一引用
- 把对象提前声明为变量,后续都用它作键
- 适合缓存 DOM 元素、React 组件实例、配置对象等真实引用场景
const keyObj = {id: 'user-100'};
const map = new Map();
<p>map.set(keyObj, {name: 'Alice', role: 'admin'});
console.log(map.get(keyObj)); // {name: 'Alice', role: 'admin'}</p><p>// 后续可安全更新
map.set(keyObj, {...map.get(keyObj), lastLogin: Date.now()});</p>
函数作键:函数也是对象,同样看引用
函数在 JS 中是一等公民,可以直接当键。常见用途包括:按处理函数分类数据、存储回调、实现策略映射。
const handlerA = () => console.log('process A');
const handlerB = (x) => x * 2;
<p>const strategyMap = new Map();
strategyMap.set(handlerA, {timeout: 3000, retry: 2});
strategyMap.set(handlerB, {timeout: 1000, retry: 0});</p><p>// 运行时根据函数引用查策略
function execute(fn, data) {
const config = strategyMap.get(fn);
if (config) console.log('Using config:', config);
return fn(data);
}</p>
⚠️ 注意:function() {} 和 () =>{} 即使逻辑一样,也是不同函数;匿名函数无法复用,不适合直接作键。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
Symbol 和原始值也能混用,但要注意隐式转换陷阱
Map 允许混合使用各种类型键,互不干扰:
const map = new Map();
<p>map.set('hello', 'string key');
map.set(42, 'number key');
map.set(true, 'boolean key');
map.set(Symbol('id'), 'symbol key');
map.set(() => {}, 'function key');
map.set({x: 1}, 'object key');</p><p>console.log(map.size); // 6 —— 全部独立</p>
⚠️ 但注意:如果误用普通对象的属性访问方式(如 map['key']),会失效——Map 不支持方括号语法取值,必须用 .get()。
实用技巧:用 WeakMap 做私有元数据(仅对象键)
如果键**只能是对象**,且希望对象被回收时自动清理对应值,用 WeakMap 更合适:
- 键必须是对象,不支持原始值
- 不阻止垃圾回收,适合存临时状态、DOM 关联数据、私有字段模拟
- 不能遍历,没有
.keys()/.values()
const privateData = new WeakMap();
<p>class User {
constructor(name) {
this.name = name;
privateData.set(this, { createdAt: Date.now(), _secret: 'shh' });
}
getSecret() {
return privateData.get(this)?._secret;
}
}</p><p>const u = new User('Bob');
console.log(u.getSecret()); // 'shh'</p>
只要 u 被销毁,privateData 中对应的条目也会被自动释放。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










