JavaScript Object Comparison Essentials

Equality Operators

When doing a comparison of anything in JavaScript you must mind your comparison operators, and almost always use the strict comparison like this === for equality and !== for non-equality. Using == and != can get you into trouble (non-strict), and I almost always default to using strict except in a few rare occasions. This is one of the different things about JavaScript as opposed to many other languages for equality comparison. So be careful, as == can be used for comparing string values to integer or floating number values in some instances, and care should be taken.

Comparison Essentials

Let’s talk a minute about primitive types in JavaScript. JavaScript primititve for the most part can be thought of as value types. So numbers, and strings are primitives, as well as null value, and undefined, and with ES6 now we also have symbols, but that is for a different post. You need to remember that when doing a comparison in JavaScript with primitive types, you are comparing their values. You can compare strings like this "String1" === "String1" and this evaluates to true as they are primitives. However, the moment you assign any value to an object it becomes a reference in memory and thus becomes a different reference and the comparison breaks down, even if all of the values of the object are the same. Note that below we are using the new keyword and thus are of Type Object.

var string1 = new String('foo');
var string2 = new String('foo');
 
console.log(string1 === string2); //evaluates false

So how do we compare value types on an object you might be asking? You may have seen an example of a string comparison function looking like the below function. Takes in parameters two string and compares them, returning a value and letting you know if they are indeed the same value as a primitive type. That is why the .toString() function is being called on each instance of a string. As in our first example of comparing the string literals, it returns true.

function stringCompare(string1, string2) {
    if (string1.toString() > string2.toString()) return -1;
    if (string1.toString() < string2.toString()) return 1;
    return 0;
}

If you are new development there a couple of things you need to keep in mind when doing a comparison of objects. I’ve got a small example below of comparing objects of the below Book class. These are some small unit tests basically showing you that even though the title, author, date of publication and publisher are the same they are referencing two different objects. It helps to use a real-world example and think if this as comparing two books. You can think about it that the books came off the print press, one after right after the other.

Unit Test Code

I’m using nodejs and mochajs to run the below unit tests as examples in the code below. If you want to run them yourself, you’ll need node and mocha framework for testing. If you have node installed you can install mocha by following the npm instructions here. I love mocha as it’s a nice dependable way for running JavaScript tests, which I’ve used in some pretty large production applications and it’s a solid testing framework. Look in the code comments for reasons and logic below. Run your mocha tests by using mocha book.js or whatever your file name is.

/*jshint esversion: 6 */
let assert = require('assert'; 
 
class Book{
    constructor(title, author, year, publisher){
        this.title = title;
        this.author = author;
        this.year = year;
        this.publisher = publisher;
    }
}
 
//one of my all-time favorite American classics
let book = new Book('The Old Man and the Sea', 'Earnest Hemingway', 1952, "Scribner's Sons");
let sameBook = new Book('The Old Man and the Sea', 'Earnest Hemingway', 1952, "Scribner's Sons");
//assign another variable to the same in-memory reference object
let cloneBook = book;
 
describe('Book', function() {
  describe('object comparison', function() {
    it('should return true for comparison', function() {
      //We are saying that these books are not the same object, even though they have the same content. 
      assert.equal(book !== sameBook, true, "These books are not the same as their reference is different");
    });
 
    it('should return true for json stringify comparison', function(){
        //this was similar to our previous string comparison example
        assert.equal(JSON.stringify(book)===JSON.stringify(sameBook), true, 
        "These json string literals are not the same.");
    });
 
    it('should return true for object comparison as they are referencing same object', function(){
        assert.equal(cloneBook === book, true); 
    });
 
  });
 
});

If you run the tests you should see something like this:

What are some ways than to compare our objects? Well, there are a couple of JavaScript libraries out there that can be helpful for doing comparisons. Underscore is probably the most widely used and supports a lot of the edge cases that can popup when comparing Objects, like Date properties for example. Basically how this works is called deep object comparison, and similar to our above string comparison function, the Underscore library has numerous such function for doing a comparison down the object tree. You could call Underscore by using something like the below snippet.

// Outputs: true
    console.log(_.isEqual(book , sameBook));

For more about JavaScript objects check out this previous post I did on JavaScript Objects and Prototypal Inheritence. As always I hope you found this useful, please subscribe for updates and share this if you found it useful. Please leave a comment below, and questions if you have them. Happy coding!