Object Diff with Underscore

by Trisox

HTML

<script src="http://underscorejs.org/underscore-min.js"></script>
<div id="debug"></div>

JavaScript

(function(_) {
  function deepDiff(a, b, r, reversible) {
		_.each(a, function (v, k) {
				// already checked this or equal...
				if (r.hasOwnProperty(k) || b[k] === v) {
					return;
				}
				// but what if it returns an empty object? still attach?
				r[k] = _.isObject(v) ? _.diff(v, b[k], reversible) : v;
			});
  }
  
    function deepDiffFullObject(a, b, r, reversible) {
    _.each(a, function(v, k) {
      // already checked this or equal...
      if (r.hasOwnProperty(k) || b[k] === v) {
        //console.log(k + ' ' + v, 'v');
        return;
      }

      if (_.isObject(v)) {      
        if(_.isEqual(v, b[k]) === false){
          r[k] = a[k]
        }
      } else {
        r[k] = v;
      }
    });
  }
  
  /* the function */
  _.mixin({
    shallowDiff: function(a, b) {
      return _.omit(a, function(v, k) {
        return b[k] === v;
      })
    },
    diff: function(a, b, reversible) {
      var r = {};
      deepDiff(a, b, r, reversible);
      if(reversible) {
        deepDiff(b, a, r, reversible);
      }
      return r;
    },
    diffReturnFullObject: function(a, b, reversible) {
      var r = {};
      deepDiffFullObject(a, b, r, reversible);
      if(reversible) {
        deepDiffFullObject(b, a, r, reversible);
      }
      return r;
    }
  });

  /* just so there's something to see */
  function dump() {
    var args = Array.prototype.slice.call(arguments);
    console.log.apply(console, args);

    var p = document.createElement('pre');
    _.each(args, function(a) {
      p.innerText += JSON.stringify(a) + '  ';
    });
    document.getElementById('debug').appendChild(p);
  }
  
  var o5 = {
      x: 1,
      z: {
        a: 1,
        b: 2,
      },
      aa: {
        a: 1,
        b: 'a',
      },
      bb: {
        a: 1,
        b: 2,
      }
    },
    o6 = {
      x: 1,
      z: {
        a: 1,
        b: 2,
      },
      aa: {
        a: 1,
        b: 2,
      },
      bb: {
        a: 1,
        b: 2,
      }
    };


 ...