【问题标题】:Reference equality for container objects容器对象的引用相等
【发布时间】:2019-01-15 00:57:37
【问题描述】:

对于特定的应用程序,我们将对象的 ID 存储在特定的类中。例如,“产品”对象会将其字符串 ID 存储在“产品 ID”对象中。同样,“用户”对象会将其字符串 id 存储在 UserId 对象中(参见下面的示例代码)。

class Product {
  id: ProductId;
  price: number;
  ...
}

class User {
  id: UserId;
  name: string;
  ...

  constructor(id: UserId, name: string) {
    this.id = id;
    this.name = name;
    ...
  }

}

class ProductId {
  id: string;

  constructor(id: string) {
    this.id = id;
  }
}

class UserId {
  id: string;

  constructor(id: string) {
    this.id = id;
  }
}

这种方法的一个问题是,将对象存储在 Map 中然后尝试检索它们(参见下面的代码)不起作用,因为具有相同基础 id 的两个 UserId 与 === 比较不相等。

const users = new Map<UserId, User>();

const user = new User(new UserId('8753098'), 'John'); 
users.set(user.id, user);

console.log(users.get(new UserId('8753098')); //undefined

似乎javascript没有运算符重载,或者没有办法覆盖相等函数。

我也想过使用全局地图,并使用静态方法创建 Id:

class UserId {

  private id: string;

  constructor(id: string) {
    this.id = id;
  }

  static userIds = new Map<string, UserId>();    

  static fromString(id: string) {
    let userId = userIds.get(id);
    if (userId === undefined) {
      userId = new UserId(id);
      userIds.set(id, userId);
    }
    return userId;
  }
}

但这有潜在的内存泄漏,因为所有对象都保留在映射中并且从未释放。

有没有人可以解决这个问题?

【问题讨论】:

  • 我不确定这是否符合您的目的,但也可以在 UserId 类中使用 toString()。然后您可以通过users.set(user.id.toString(), user); 获取/设置

标签: javascript typescript


【解决方案1】:

有没有人可以解决这个问题?

而不是class UserId,只需输入type UserId = string

更多

如果您担心结构平等并且更喜欢名义类型,您可以使用枚举添加品牌 as shown here

enum UserIdBrand {}
type UserId = UserIdBrand & string;

【讨论】:

  • 非常有趣的文章
猜你喜欢
  • 2012-05-11
  • 2012-03-16
  • 1970-01-01
  • 2023-04-05
  • 2020-07-15
  • 2020-09-15
  • 1970-01-01
  • 2015-07-26
  • 1970-01-01
相关资源
最近更新 更多