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

新手上路,请多包涵

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

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

原文由 user4903 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 597
2 个回答

简短的回答

简单的答案是:不,没有通用的方法可以确定一个对象与您所说的另一个对象相等。例外情况是当您严格认为对象是无类型的时。

长答案

这个概念是 Equals 方法的概念,它比较对象的两个不同实例以指示它们在值级别是否相等。但是,如何实现 Equals 方法取决于具体类型。具有原始值的属性的迭代比较可能是不够的:一个对象可能包含与相等性无关的属性。例如,

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

在上述情况下, c 对于确定 MyClass 的任何两个实例是否相等并不重要,只有 ab 很重要。在某些情况下, c 可能会因实例而异,但在比较期间并不显着。

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

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

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

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

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

原文由 AnthonyWJones 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

 _.isEqual(object, other);

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

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

原文由 coolaj86 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题