jQuery/JavaScript JSON object comparison

What I want to do is take the object that was just polled and compare it to a stored one. Where if there is any changes from one to the other apply them to the stored object or replace it (either way)

If you would be happy with a really simple "Has it changed in any way? Yes/No" solution, where if it has changed you just replace the previous object with the new one (as per the part of your question that I quoted), then you could save the JSON response before you parse it, i.e., save it in the string format in which your web-server sends it. Then when the next response comes in compare the new string with the old string. If they are different (or if it is the first request) parse the JSON and process it for display as appropriate. Naturally this assumes that your server-side code is creating the JSON strings in a consistent format (and not, e.g., changing the order of the properties).

If we assume you've already got (parsed) objects, an isEqual(a,b) function really should cope with nested objects, properties that are arrays, etc. This can be done recursively, and simply return true or false, but a getDifferences(a,b) function is going to get confusing in how it reports the differences within nested objects. Consider this simple example:

old: {"mum" : "Maria", "dad" : "Pierre", "kids" : ["Joe", "Mike", "Louisa"] }
new: {"mum" : "Julie", "dad" : "Pierre", "kids" : ["Joe", "Mary"] }

Is the difference {"mum" : "Julie", "kids" : ["Mary"]}? The "mum" has changed, and the list of "kids" has changed, but has "Mike" changed to "Mary", or are both "Mike" and "Louisa" gone with "Mary" being new, or...? Maybe it should be "kids": ["Joe","Mary"] because that's the new value. How do you indicate the deletions? That's just the first example off the top of my head where I don't know how you would want to handle the differences. It could quickly get worse: what if the "kids" array contained objects instead of strings to represent a whole family tree? What if the new "mum" property was ["Maria", "Julie"] (to allow for step-parents and so forth)?

If for your particular data you know you've only got one-dimensional objects then you can do something simple like the following:

function getDifferences(oldObj, newObj) {
   var diff = {};

   for (var k in oldObj) {
      if (!(k in newObj))
         diff[k] = undefined;  // property gone so explicitly set it undefined
      else if (oldObj[k] !== newObj[k])
         diff[k] = newObj[k];  // property in both but has changed
   }

   for (k in newObj) {
      if (!(k in oldObj))
         diff[k] = newObj[k]; // property is new
   }

   return diff;
}

The simplest change to the above to allow for nested objects is to just assume that if a property is an object/array then you only care whether it is different in any way and not dig down to report exactly which "sub-properties" have changed. If so, simply take the above function and change:

else if (oldObj[k] !== newObj[k])

to

else if (!isEqual(oldObj[k],newObj[k]))

Where isEqual() is one of the many comparison functions floating around the web or on StackOverflow.

(Note: I haven't bothered with .hasOwnProperty() above because I assume that objects that were returned to an Ajax request as JSON will not be inheriting properties from a prototype chain. Similarly an isEqual() function for this purpose wouldn't need to worry about properties being functions, it only needs to worry about what is valid in a JSON string.)


Sorry to answer old thread but my answer may help others who may face the same issue.the most easiest & shortest code to compare two json object as follows. thanks

<script type="text/javascript">
    $(document).ready(function () {
        var a = { "id": "210", "memberlist": "john" };
        var b = { "id": "210", "memberlist": "john1" };

        alert(JSON.stringify(a) != JSON.stringify(b) ? 'not same' : ' same');
    });
</script>