UNPKG

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