如何确定两个 JavaScript 对象的相等性?

2022-08-29 22:15:06

严格的相等运算符将告诉您两个对象类型是否相等。但是,有没有办法判断两个对象是否相等,就像Java中的哈希代码值一样?

堆栈溢出问题 JavaScript 中是否有任何类型的 hashCode 函数?与此问题类似,但需要更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有任何等效的解决方案


答案 1

为什么要重新发明轮子?试试洛达什吧。它具有许多必备函数,例如 isEqual()。

_.isEqual(object, other);

它将使用 ECMAScript 5 和本机优化(如果它们在浏览器中可用)暴力检查每个键值 - 就像此页面上的其他示例一样。

注意:以前这个答案建议Underscore.js,但lodash在修复错误和解决一致性问题方面做得更好。


答案 2

简短的回答

简单的答案是:不,没有通用的方法来确定一个对象等于你所指意义上的另一个对象。例外情况是,当您严格认为对象是无类型对象时。

长答案

这个概念是 Equals 方法的概念,该方法比较对象的两个不同实例,以指示它们在值级别是否相等。但是,由特定类型来定义应如何实现方法。对具有基元值的属性进行迭代比较可能还不够:对象可能包含与相等性无关的属性。例如Equals

 function MyClass(a, b)
 {
     var c;
     this.getCLazy = function() {
         if (c === undefined) c = a * b // imagine * is really expensive
         return c;
     }
  }

在上述情况下,确定 MyClass 的任何两个实例是否相等并不重要,只有并且是否重要。在某些情况下,实例之间可能会有所不同,但在比较过程中并不显著。cabc

请注意,当成员本身也可能是某种类型的实例并且这些成员都需要具有确定相等性的方法时,此问题适用。

更复杂的是,在JavaScript中,数据和方法之间的区别是模糊的。

对象可能引用要作为事件处理程序调用的方法,这可能不会被视为其“值状态”的一部分。而另一个对象很可能被分配一个执行重要计算的函数,从而使该实例与其他实例不同,仅仅是因为它引用了不同的函数。

如果一个对象的一个现有的原型方法被另一个函数覆盖了呢?它是否仍可被视为等同于另一个在其他方面相同的实例?这个问题只能在每种类型的每个特定情况下回答。

如前所述,例外将是严格的无类型对象。在这种情况下,唯一明智的选择是每个成员的迭代和递归比较。即便如此,人们也不得不问,函数的“值”是什么?