code: function isEqual(a, b, callback, thisArg) {
        return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
      }
docs: Performs a deep comparison between two values to determine if they are
  equivalent to each other. If a callback is provided it will be executed
  to compare values. If the callback returns `undefined` comparisons will
  be handled by the method instead. The callback is bound to `thisArg` and
  invoked with two arguments; (a, b).
  
  @static
  @memberOf _
  @category Objects
  @param {*} a The value to compare.
  @param {*} b The other value to compare.
  @param {Function} [callback] The function to customize comparing values.
  @param {*} [thisArg] The `this` binding of `callback`.
  @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  @example
  
  var object = { 'name': 'fred' };
  var copy = { 'name': 'fred' };
  
  object == copy;
  // => false
  
  _.isEqual(object, copy);
  // => true
  
  var words = ['hello', 'goodbye'];
  var otherWords = ['hi', 'goodbye'];
  
  _.isEqual(words, otherWords, function(a, b) {
  var reGreet = /^(?:hello|hi)$/i,
  aGreet = _.isString(a) && reGreet.test(a),
  bGreet = _.isString(b) && reGreet.test(b);
  
  return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
  });
  // => true