Alex Rivera | Logout

How can I determine equality for two JavaScript objects?

Asked 2008-10-14T13:41:07.357
1037

A strict equality operator will tell you if two object types are equal. However, is there a way to tell if two objects are equal, much like the hash code value in Java?

Stack Overflow question Is there any kind of hashCode function in JavaScript? is similar to this question, but requires a more academic answer. The scenario above demonstrates why it would be necessary to have one, and I'm wondering if there is any equivalent solution.

Edit
Report

5 Answers

726

Give the Lodash library a try. It has a number of must-have functions such as isEqual().

_.isEqual(object, other);

It will brute force check each key value—just like the other examples on this page—using ECMAScript 5 and native optimizations if they're available in the browser.

Note: Previously this answer recommended Underscore.js, but Lodash has done a better job of getting bugs fixed and addressing issues with consistency.

Reviewer Note: Lodash library had not had a release since 2015, but it is now being actively maintained in GitHub since 2023 with pull requests up to at least the date of this edit.

answered 2010-07-07T19:35:38.133
23

If you have a deep copy function handy, you can use the following trick to still use JSON.stringify while matching the order of properties:

function equals(obj1, obj2) {
    function _equals(obj1, obj2) {
        return JSON.stringify(obj1)
            === JSON.stringify($.extend(true, {}, obj1, obj2));
    }
    return _equals(obj1, obj2) && _equals(obj2, obj1);
}

Demo: http://jsfiddle.net/CU3vb/3/

Rationale:

Since the properties of obj1 are copied to the clone one by one, their order in the clone will be preserved. And when the properties of obj2 are copied to the clone, since properties already existing in obj1 will simply be overwritten, their orders in the clone will be preserved.

answered 2012-06-14T19:20:48.377
3

Here is a more generic object comparison function than what has ben posted thus far:

Object.prototype.equals = function(iObj) {
  if (this.constructor !== iObj.constructor)
    return false;
  var aMemberCount = 0;
  for (var a in this) {
    if (!this.hasOwnProperty(a))
      continue;
    if (typeof this[a] === 'object' && typeof iObj[a] === 'object' ? !this[a].equals(iObj[a]) : this[a] !== iObj[a])
      return false;
    ++aMemberCount;
  }
  for (var a in iObj)
    if (iObj.hasOwnProperty(a))
      --aMemberCount;
  return aMemberCount ? false : true;
}
answered 2010-05-27T12:00:59.313
2

I'd advise against hashing or serialization (as the JSON solution suggest). If you need to test if two objects are equal, then you need to define what equals means. It could be that all data members in both objects match, or it could be that must the memory locations match (meaning both variables reference the same object in memory), or may be that only one data member in each object must match.

Recently I developed an object whose constructor creates a new id (starting from 1 and incrementing by 1) each time an instance is created. This object has an isEqual function that compares that id value with the id value of another object and returns true if they match.

In that case I defined "equal" as meaning the the id values match. Given that each instance has a unique id this could be used to enforce the idea that matching objects also occupy the same memory location. Although that is not necessary.

answered 2008-11-19T16:20:00.590
-1

Depends on what you mean by equality. And therefore it is up to you, as the developer of the classes, to define their equality.

There's one case used sometimes, where two instances are considered 'equal' if they point to the same location in memory, but that is not always what you want. For instance, if I have a Person class, I might want to consider two Person objects 'equal' if they have the same Last Name, First Name, and Social Security Number (even if they point to different locations in memory).

On the other hand, we can't simply say that two objects are equal if the value of each of their members is the same, since, sometimes, you don't want that. In other words, for each class, it's up to the class developer to define what members make up the objects 'identity' and develop a proper equality operator (be it via overloading the == operator or an Equals method).

Saying that two objects are equal if they have the same hash is one way out. However you then have to wonder how the hash is calculated for each instance. Going back to the Person example above, we could use this system if the hash was calculated by looking at the values of the First Name, Last Name, and Social Security Number fields. On top of that, we are then relying on the quality of the hashing method (that's a huge topic on its own, but suffice it to say that not all hashes are created equal, and bad hashing methods can lead to more collisions, which in this case would return false matches).

answered 2008-10-14T13:54:31.993

Your Answer