You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.8 KiB

4 years ago
  1. var getAllKeys = require('./_getAllKeys');
  2. /** Used to compose bitmasks for value comparisons. */
  3. var COMPARE_PARTIAL_FLAG = 1;
  4. /** Used for built-in method references. */
  5. var objectProto = Object.prototype;
  6. /** Used to check objects for own properties. */
  7. var hasOwnProperty = objectProto.hasOwnProperty;
  8. /**
  9. * A specialized version of `baseIsEqualDeep` for objects with support for
  10. * partial deep comparisons.
  11. *
  12. * @private
  13. * @param {Object} object The object to compare.
  14. * @param {Object} other The other object to compare.
  15. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  16. * @param {Function} customizer The function to customize comparisons.
  17. * @param {Function} equalFunc The function to determine equivalents of values.
  18. * @param {Object} stack Tracks traversed `object` and `other` objects.
  19. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  20. */
  21. function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
  22. var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
  23. objProps = getAllKeys(object),
  24. objLength = objProps.length,
  25. othProps = getAllKeys(other),
  26. othLength = othProps.length;
  27. if (objLength != othLength && !isPartial) {
  28. return false;
  29. }
  30. var index = objLength;
  31. while (index--) {
  32. var key = objProps[index];
  33. if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
  34. return false;
  35. }
  36. }
  37. // Assume cyclic values are equal.
  38. var stacked = stack.get(object);
  39. if (stacked && stack.get(other)) {
  40. return stacked == other;
  41. }
  42. var result = true;
  43. stack.set(object, other);
  44. stack.set(other, object);
  45. var skipCtor = isPartial;
  46. while (++index < objLength) {
  47. key = objProps[index];
  48. var objValue = object[key],
  49. othValue = other[key];
  50. if (customizer) {
  51. var compared = isPartial
  52. ? customizer(othValue, objValue, key, other, object, stack)
  53. : customizer(objValue, othValue, key, object, other, stack);
  54. }
  55. // Recursively compare objects (susceptible to call stack limits).
  56. if (!(compared === undefined
  57. ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
  58. : compared
  59. )) {
  60. result = false;
  61. break;
  62. }
  63. skipCtor || (skipCtor = key == 'constructor');
  64. }
  65. if (result && !skipCtor) {
  66. var objCtor = object.constructor,
  67. othCtor = other.constructor;
  68. // Non `Object` object instances with different constructors are not equal.
  69. if (objCtor != othCtor &&
  70. ('constructor' in object && 'constructor' in other) &&
  71. !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
  72. typeof othCtor == 'function' && othCtor instanceof othCtor)) {
  73. result = false;
  74. }
  75. }
  76. stack['delete'](object);
  77. stack['delete'](other);
  78. return result;
  79. }
  80. module.exports = equalObjects;