1 var equalArrays = require('./equalArrays'),
2 equalByTag = require('./equalByTag'),
3 equalObjects = require('./equalObjects'),
4 isArray = require('../lang/isArray'),
5 isTypedArray = require('../lang/isTypedArray');
7 /** `Object#toString` result references. */
8 var argsTag = '[object Arguments]',
9 arrayTag = '[object Array]',
10 objectTag = '[object Object]';
12 /** Used for native method references. */
13 var objectProto = Object.prototype;
15 /** Used to check objects for own properties. */
16 var hasOwnProperty = objectProto.hasOwnProperty;
19 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
22 var objToString = objectProto.toString;
25 * A specialized version of `baseIsEqual` for arrays and objects which performs
26 * deep comparisons and tracks traversed objects enabling objects with circular
27 * references to be compared.
30 * @param {Object} object The object to compare.
31 * @param {Object} other The other object to compare.
32 * @param {Function} equalFunc The function to determine equivalents of values.
33 * @param {Function} [customizer] The function to customize comparing objects.
34 * @param {boolean} [isLoose] Specify performing partial comparisons.
35 * @param {Array} [stackA=[]] Tracks traversed `value` objects.
36 * @param {Array} [stackB=[]] Tracks traversed `other` objects.
37 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
39 function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
40 var objIsArr = isArray(object),
41 othIsArr = isArray(other),
46 objTag = objToString.call(object);
47 if (objTag == argsTag) {
49 } else if (objTag != objectTag) {
50 objIsArr = isTypedArray(object);
54 othTag = objToString.call(other);
55 if (othTag == argsTag) {
57 } else if (othTag != objectTag) {
58 othIsArr = isTypedArray(other);
61 var objIsObj = objTag == objectTag,
62 othIsObj = othTag == objectTag,
63 isSameTag = objTag == othTag;
65 if (isSameTag && !(objIsArr || objIsObj)) {
66 return equalByTag(object, other, objTag);
69 var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
70 othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
72 if (objIsWrapped || othIsWrapped) {
73 return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
79 // Assume cyclic values are equal.
80 // For more information on detecting circular references see https://es5.github.io/#JO.
81 stackA || (stackA = []);
82 stackB || (stackB = []);
84 var length = stackA.length;
86 if (stackA[length] == object) {
87 return stackB[length] == other;
90 // Add `object` and `other` to the stack of traversed objects.
94 var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
102 module.exports = baseIsEqualDeep;