我正在尝试通过 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/