TypeScript中以对象为键的Map.has()方法失效问题求助
问题分析与解决方案
你遇到的这个问题其实是 JavaScript/TypeScript 内置 Map 的特性导致的——它根本不会调用你自定义的 equals 方法来判断键是否相等。Map.has() 用的是 SameValueZero 比较算法,对于对象类型的键来说,只有当两个对象是同一个内存引用时,才会被判定为相等,完全无视你写的 equals 逻辑。
下面给你几个可行的解决思路:
方案1:用对象的唯一标识作为键(最推荐)
既然你的 MyObject1 有唯一的 id 属性,直接把 id 作为 Map 的键是最简单高效的方案,这样只要 id 匹配,就能正确判断存在性:
// 调整Map的键类型为id的类型(比如number或string) const myMap: Map<string | number, MyObject2> = new Map(); // 存储时用对象的id作为键 myMap.set(myObject1.id, myObject2); // 判断时传入目标对象的id即可 const isExists = myMap.has(targetObject.id);
方案2:封装支持自定义相等判断的Map类
如果你必须用对象本身作为键,可以自己封装一个轻量的自定义Map,内部用你的equals逻辑来匹配键:
class CustomEqualityMap<K, V> { private entries: Array<{ key: K; value: V }> = []; // 构造时传入自定义的相等判断函数 constructor(private equals: (a: K, b: K) => boolean) {} set(key: K, value: V): void { const matchIndex = this.entries.findIndex(entry => this.equals(entry.key, key)); if (matchIndex !== -1) { // 存在则更新值 this.entries[matchIndex].value = value; } else { // 不存在则新增 this.entries.push({ key, value }); } } has(key: K): boolean { return this.entries.some(entry => this.equals(entry.key, key)); } get(key: K): V | undefined { return this.entries.find(entry => this.equals(entry.key, key))?.value; } } // 使用时传入你的id相等判断逻辑 const myMap = new CustomEqualityMap<MyObject1, MyObject2>((a, b) => a.id === b.id); myMap.set(myObject1, myObject2); console.log(myMap.has(targetObject)); // 现在会根据id正确返回结果
补充说明:为什么自定义equals不生效?
和 Java 这类语言不同,JavaScript 的内置集合(Map/Set)没有提供重写键相等逻辑的接口,它们的比较规则是固定的:
- 对于原始类型(string/number等),比较值是否相等
- 对于对象类型,比较是否是同一个引用
所以你写的 equals 方法只是对象的一个普通方法,Map 完全不会主动调用它。
内容的提问来源于stack exchange,提问作者1Z10
相关产品推荐
相关产品推荐

