import Stack from './Stack.js' import equalArrays from './equalArrays.js' import equalByTag from './equalByTag.js' import equalObjects from './equalObjects.js' import getTag from './getTag.js' import isBuffer from '../isBuffer.js' import isTypedArray from '../isTypedArray.js' /** Used to compose bitmasks for value comparisons. */ const COMPARE_PARTIAL_FLAG = 1 /** `Object#toString` result references. */ const argsTag = '[object Arguments]' const arrayTag = '[object Array]' const objectTag = '[object Object]' /** Used to check objects for own properties. */ const hasOwnProperty = Object.prototype.hasOwnProperty /** * A specialized version of `baseIsEqual` for arrays and objects which performs * deep comparisons and tracks traversed objects enabling objects with circular * references to be compared. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} [stack] Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { let objIsArr = Array.isArray(object) const othIsArr = Array.isArray(other) let objTag = objIsArr ? arrayTag : getTag(object) let othTag = othIsArr ? arrayTag : getTag(other) objTag = objTag == argsTag ? objectTag : objTag othTag = othTag == argsTag ? objectTag : othTag let objIsObj = objTag == objectTag const othIsObj = othTag == objectTag const isSameTag = objTag == othTag if (isSameTag && isBuffer(object)) { if (!isBuffer(other)) { return false } objIsArr = true objIsObj = false } if (isSameTag && !objIsObj) { stack || (stack = new Stack) return (objIsArr || isTypedArray(object)) ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack) } if (!(bitmask & COMPARE_PARTIAL_FLAG)) { const objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__') const othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__') if (objIsWrapped || othIsWrapped) { const objUnwrapped = objIsWrapped ? object.value() : object const othUnwrapped = othIsWrapped ? other.value() : other stack || (stack = new Stack) return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack) } } if (!isSameTag) { return false } stack || (stack = new Stack) return equalObjects(object, other, bitmask, customizer, equalFunc, stack) } export default baseIsEqualDeep