gpt4 book ai didi

typescript : Object Equality Comparison (Object Equals Object)

转载 作者:行者123 更新时间:2023-12-03 19:37:17 24 4
gpt4 key购买 nike

我发现这个(个人)方便的答案适合我的需要:
https://stackoverflow.com/a/6713782/2678218

但由于我使用的是 typescript , 我可以用 做这样的事情泛型 :

private equals<T>(x: T, y: T) {
if (x === y) {
return true; // if both x and y are null or undefined and exactly the same
} else if (!(x instanceof Object) || !(y instanceof Object)) {
return false; // if they are not strictly equal, they both need to be Objects
} else if (x.constructor !== y.constructor) {
// they must have the exact same prototype chain, the closest we can do is
// test their constructor.
return false;
} else {
for (const p in x) {
if (!x.hasOwnProperty(p)) {
continue; // other properties were tested using x.constructor === y.constructor
}
if (!y.hasOwnProperty(p)) {
return false; // allows to compare x[ p ] and y[ p ] when set to undefined
}
if (x[p] === y[p]) {
continue; // if they have the same strict value or identity then they are equal
}
if (typeof (x[p]) !== 'object') {
return false; // Numbers, Strings, Functions, Booleans must be strictly equal
}
if (!this.equals(x[p], y[p])) {
return false;
}
}
for (const p in y) {
if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) {
return false;
}
}
return true;
}
}

我敢肯定,因为我们正在使用 <T>在这里,我们可以重构代码。可以肯定的是删除一些 if不再需要的语句。但是我不确定要拿走哪个,也不确定是否会有更优化的代码。所以我把问题留在这里,让大家投票选出最佳答案。

在这种情况下,我所说的两个对象相等的实际意思是指相同类型的两个对象的每个属性都具有相等的值。

最佳答案

@Lostfields 提到有人可以通过 any对于类型 T ,但这不是一个大问题,因为使用 any告诉编译器不要键入检查任何内容。如果这在运行时导致不良行为,我会将处理此问题的责任放在传入 any 的代码上。 , 而不是 equals() 里面的代码.类型系统的一种用途确实是消除一些不必要的运行时检查,但需要注意的是,您仍然需要清理从不受信任的来源传入的任何数据。您是否正在构建一个可供甚至可能不使用 TypeScript 的开发人员使用的库?然后不要放松任何运行时检查。您是在构建要在内部使用还是由其他依赖于您的类型的 TypeScript 开发人员使用的代码?然后通过一切手段消除不必要的检查。

话虽如此,我不知道您可以删除该实现中的许多检查。检查的每个条件可能是 truefalse在运行时,即使知道 TypeScript 已经决定 xy属于同一类型。 (在接下来的内容中,我将 equals() 视为一个独立的函数而不是一个方法。添加 this 或任何您认为合适的对象名称)

让我们逐一检查:

  • (x === y) :适用于 equals(x,x) , 假为 equals(x, Object.assign({},x)) .这个必须留下。
  • ((!(x instanceof Object) || !(y instanceof Object)) :您可能决定用 (!(x instanceof Object)) 替换这个,因为实际上 TypeScript 中的类型要么是 Object或者不是,等等 x instanceof Object应该与 y instanceof Object 相同.不过,有人可能会这样做 equals(0, new Number(0))它通过了 TypeScript 中的类型检查。如果你关心防范那个,这取决于你。
  • (x.constructor !== y.constructor) :对于两个结构相同的类,例如 class A{}; class B{}; equals(new A(), new B()) 为 False .如果您不担心结构相同但不同的类,则可以取消此检查。
  • (!x.hasOwnProperty(p)) :这个检查与TypeScript无关;它必须留下来。

  • 对于下一种情况,请考虑
    interface Foo { foo?: string, bar: number, baz?: boolean };
    const x: Foo = { foo: 'hello', bar: 12 };
    const y: Foo = { bar: 12, baz: false };
    equals(x, y);
  • (!y.hasOwnProperty(p))(y.hasOwnProperty(p) && !x.hasOwnProperty(p)) :对于 Foo 的实例,这些可能是对的或错的,或任何具有可选属性的类型。或者没有可选属性的类型的任何子类型,因为 TypeScript 允许额外的属性。
  • (x[p] === y[p]) , (typeof (x[p]) !== 'object') , (!equals(x[p], y[p])) :这些可以为真,也可以为假,原因与上述相同,可以通过传入具有上述类型的单个属性的类型来查看。也就是说,如果 equals(x,y)需要运行时检查,然后 equals({foo: x},{foo: y})将需要相同的运行时检查。


  • 所以,这取决于你。随意离开实现。毕竟,额外的运行时检查不会造成任何伤害。如果您认为不需要它们,请随意删除一些检查;再说一次,你是唯一知道 equals()的用户有多疯狂的人。将会。例如,你会怎么做:
    interface Ouroboros {
    prop: Ouroboros;
    }
    let x = {} as Ouroboros;
    x.prop = x;

    let y = {} as Ouroboros;
    y.prop = y;

    console.log(equals(x,y))

    你关心循环引用吗?如果没有,请不要担心。如果是这样,那么你需要加强你的平等检查来处理它。

    希望有所帮助;祝你好运!

    关于 typescript : Object Equality Comparison (Object Equals Object),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46705216/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com