JSON Patch using Underscore

HTML

<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="https://raw.github.com/bruth/jsonpatch-js/master/jsonpatch.js"></script>

JavaScript

var obj1 = {
    4: 'e',
    1: ['a', 'c', 5]
};

var obj2 = {
    5: ['a', 'c', 5],
    2: {
        4: 'e'
    },
    3: 'b',
};

// Patch helper functions
  function getParent(paths, path) {
    return paths[path.substr(0, path.match(/\//g).length)];
  }

  // Checks if `obj` is an array or object
  function isContainer(obj) {
    return _.isArray(obj) || _.isObject(obj);
  }

  // Checks if the two objects are of the same container type
  function isSameContainer(obj1, obj2) {
      return (_.isArray(obj1) && _.isArray(obj2)) || (_.isObject(obj1) && _.isObject(obj2));
  }

  // Flattens an object to a hash of paths and values.
  function flattenObject(obj, prefix, paths) {
    prefix || (prefix = '/');
    paths || (paths = {});

    // Do not bother logging the root path
    paths[prefix] = {
      path: prefix,
      value: obj
    };

    prefix !== '/' && (prefix = prefix + '/')

    // Recurse for container types
    if (_.isArray(obj)) {
      for (var i = 0, l = obj.length; i < l; i++) {
        flattenObject(obj[i], prefix + i, paths);
      }
    } else if (_.isObject(obj)) {
      for (var key in obj) {
        flattenObject(obj[key], prefix + key, paths);
      }
    }

    return paths;
  }

  // Constructs a patch that when applied to `obj2`, it will be equivalent
  // to `obj1`. The patch format conforms to IETF JSON Patch proposal
  // http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-01
  function constructPatch(obj1, obj2) {
    // Patches are only applicable to two of the same container types.
    if (!isSameContainer(obj1, obj2)) {
      throw new Error('Patches can only be derived from objects or arrays');
    }

    var paths1 = flattenObject(obj1),
      paths2 = flattenObject(obj2),
      key1,
      key2,
      doc1,
      doc2,
      patch = [],
      add = {},
      remove = {},
      replace = {},
      move = {};

    // Iterate over the first object's paths and compare them to the second
    // set of paths.
    for (key1...