【问题标题】:Map doesn't find entry by object key地图找不到对象键的条目
【发布时间】:2020-01-22 08:18:07
【问题描述】:

当键是对象时,我使用的是 Map 对象,由接口表示。 由于某种原因,地图找不到条目。

查看我的代码:

export interface IMyObject
{
    property1 : string;
    property2 : number;
} 

在我的组件中:

MyMap : Map/*WeakMap*/<IMyObject, number[]> = new Map();

let key = { property1 : "AAA", property2: 1  } as IMyObject;
this.MyMap.set(key, [2,3,4,5]); 

取决于事件处理程序:

let mapKey = { property1: "AAA", property2: 1 } as IMyObject;
var A = this.MyMap.has(mapKey); //return false

我在这里错过了什么?

【问题讨论】:

  • 一般来说它可以工作,你应该像这样照顾你的实例:this.MyMap 是所需的变量并具有所需的值。也许地图对象在此期间被清除了。
  • 使用对象作为键,是一件坏事。你的对象键!= mapKey。两个对象具有相同的属性和值,但不是同一个对象。
  • 对象通过引用进行比较。检查存在时,您确定有 same 对象吗? console.log(new Map([[{}, 'There']]).has({}))
  • 您不能将相同的密钥与新的密钥对象进行比较。对象引用延迟两者。检查以下解决方案
  • @GuyE 不幸的是,您不能覆盖对象的相等性检查。所以将它们作为键并没有那么有用。

标签: angular typescript dictionary ecmascript-5


【解决方案1】:

当您说this.MyMap.has(key) 而不是新创建的对象mapKey 时,它会起作用。这可能是因为在 JavaScript 中创建一个对象时,它存储有一个特定的内存 ID,该内存 ID 在对象之间是不同的,MyMap.has(...) 可能会检查该位置/内存 ID,而不是该对象是否实际匹配一个键。 这也是为什么不能用简单的相等操作比较对象的原因。

const a = { prop1: "AAA", prop2: 1 };
const b = { prop1: "AAA", prop2: 1 };
console.log(a == b); //=> false

无论如何,我认为将对象作为映射中的键是一种不好的做法,但是 YMMV。

要解决此问题,您需要设置一个全局对象,将其添加到地图中,并仅使用它来检查地图是否已将所述对象作为键。

【讨论】:

    【解决方案2】:
    export interface IMyObject
    {
        property1 : string;
        property2 : number;
    }
    
    let  MyMap  = new Map<IMyObject,number[]>();
    
    let key = { property1 : "AAA", property2: 1  };
    MyMap.set(key, [2,3,4,5]);
    
    var b = MyMap.get(key); 
    var A = MyMap.has(key); 
    console.log(b);
    console.log(A);
    

    【讨论】:

      猜你喜欢
      • 2020-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多