javascript - 如何在使用 ES6 的 Set 集合时检查类实例的相等性和相同性?

标签 javascript typescript ecmascript-6 set typescript-typings

我正在尝试通过 lib.es6.d.ts 从 TypeScript 使用 ES6 。我需要了解如何enforce equality comparison and sameness用于 Set<T> 中使用的对象。例如,该对象如下所示。

class Product {
 metadata: Map<String, String>

 constructor(id: number) { 
  metadata = new Map<String, String>();
 }

 public addMetadata(key: String, val: String): Product {
  this.metadata.set(key, val);
  return this;
 }
}

请注意id Product 中的字段值决定了它的独特性。如果两个 Product 实例具有相同的 id,则它们在我的应用程序中被视为相同,即使 metadata不同。一般来说,我只想将字段的子集用作相等性和相同性测试的一部分。

在 Java 中,我们覆盖 equals控制和测试相同性的方法。在 JavaScript 中,我们需要做什么来确定相同性?

link on MDN声明如下:

Because each value in the Set has to be unique, the value equality will be checked.

我认为值(value)相等意味着=== ?再次,MDN shows 4 equality algorithms仅在 ES2015 中。

基本上,在我上面的类(class)中,我想做如下的事情。

let p1 = new Product(1);
let p2 = new Product(2);
let p3 = new Product(1); //duplicate of p1 by id

p1.addMetadata('k1','v1').addMetadata('k2','v2');
p2.addMetadata('k1','v1');

let mySet = new Set<Product>();
mySet.add(p1);
mySet.add(p2);
mySet.add(p3);

assertEquals(2, mySet.size); //some assertion method

最佳答案

检查对象是否相等的简单(也是高性能)方法是比较 JSON.stringify() 字符串。由于只有自己的可枚举属性被字符串化,metadata 属性应该是不可枚举的:

class Product {
 metadata: Map<String, String>

 constructor(public id: number) { 
     Object.defineProperty(this, 'metadata', {
         configurable: true,
         writable: true
     })

     this.metadata = new Map<String, String>(); 
 }
 ...
}

这将导致:

new Product(1) !== new Product(1);
JSON.stringify(new Product(1)) === JSON.stringify(new Product(1));
JSON.stringify(new Product(1)) !== JSON.stringify(new Product(2));

此方法可以在自定义Set中使用:

class ObjectedSet extends Set {
  protected _find(searchedValue) {
    for (const value of Array.from(this.values()))
      if (JSON.stringify(value) === JSON.stringify(searchedValue))
        return searchedValue;
  }

  has(value) {
    return !!this._find(value);
  }

  add(value) {
    if (!this.has(value))
      super.add(value);

    return this;
  }

  delete(value) {
    const foundValue = this._find(value);

    if (foundValue)
      super.delete(foundValue);

    return !!foundValue;
  }
}

关于javascript - 如何在使用 ES6 的 Set 集合时检查类实例的相等性和相同性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41156840/

相关文章:

javascript - 如何检查javascript字符串中是否存在数字

reactjs - 使用 docker compose 运行 TypeScript React 应用程序时出错

javascript - 将 $compile 注入(inject)指令未定义

javascript - 在 Redux (React) 中调用存储调度后, View 不想重新渲染

javascript - Spread Operator 获取数组内对象的单个属性 - JS/TS

javascript - 显示 : fullscreen doesn't work on manifest json

javascript - 使用 Knockout.JS 如何使用自定义绑定(bind)处理程序附加事件处理程序

Javascript:图像更改

javascript - 如何使用 window.scrollTo 在元素内滚动?

javascript - Reactjs - 类型错误 : Failed to execute 'fetch' on 'Window' : Failed to parse URL from ***. **.*.***:2000