baseIsEqualDeep.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import Stack from './Stack';
  2. import equalArrays from './equalArrays';
  3. import equalByTag from './equalByTag';
  4. import equalObjects from './equalObjects';
  5. import getTag from './getTag';
  6. import isArray from '../isArray';
  7. import isHostObject from './isHostObject';
  8. import isTypedArray from '../isTypedArray';
  9. /** Used to compose bitmasks for comparison styles. */
  10. var PARTIAL_COMPARE_FLAG = 2;
  11. /** `Object#toString` result references. */
  12. var argsTag = '[object Arguments]',
  13. arrayTag = '[object Array]',
  14. objectTag = '[object Object]';
  15. /** Used for built-in method references. */
  16. var objectProto = Object.prototype;
  17. /** Used to check objects for own properties. */
  18. var hasOwnProperty = objectProto.hasOwnProperty;
  19. /**
  20. * A specialized version of `baseIsEqual` for arrays and objects which performs
  21. * deep comparisons and tracks traversed objects enabling objects with circular
  22. * references to be compared.
  23. *
  24. * @private
  25. * @param {Object} object The object to compare.
  26. * @param {Object} other The other object to compare.
  27. * @param {Function} equalFunc The function to determine equivalents of values.
  28. * @param {Function} [customizer] The function to customize comparisons.
  29. * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
  30. * @param {Object} [stack] Tracks traversed `object` and `other` objects.
  31. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  32. */
  33. function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
  34. var objIsArr = isArray(object),
  35. othIsArr = isArray(other),
  36. objTag = arrayTag,
  37. othTag = arrayTag;
  38. if (!objIsArr) {
  39. objTag = getTag(object);
  40. if (objTag == argsTag) {
  41. objTag = objectTag;
  42. } else if (objTag != objectTag) {
  43. objIsArr = isTypedArray(object);
  44. }
  45. }
  46. if (!othIsArr) {
  47. othTag = getTag(other);
  48. if (othTag == argsTag) {
  49. othTag = objectTag;
  50. } else if (othTag != objectTag) {
  51. othIsArr = isTypedArray(other);
  52. }
  53. }
  54. var objIsObj = objTag == objectTag && !isHostObject(object),
  55. othIsObj = othTag == objectTag && !isHostObject(other),
  56. isSameTag = objTag == othTag;
  57. if (isSameTag && !(objIsArr || objIsObj)) {
  58. return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
  59. }
  60. var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
  61. if (!isPartial) {
  62. var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
  63. othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
  64. if (objIsWrapped || othIsWrapped) {
  65. return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
  66. }
  67. }
  68. if (!isSameTag) {
  69. return false;
  70. }
  71. stack || (stack = new Stack);
  72. return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
  73. }
  74. export default baseIsEqualDeep;