_equalObjects.js (2971B)
1 var getAllKeys = require('./_getAllKeys'); 2 3 /** Used to compose bitmasks for value comparisons. */ 4 var COMPARE_PARTIAL_FLAG = 1; 5 6 /** Used for built-in method references. */ 7 var objectProto = Object.prototype; 8 9 /** Used to check objects for own properties. */ 10 var 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 */ 25 function 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 // Check that cyclic values are equal. 43 var objStacked = stack.get(object); 44 var othStacked = stack.get(other); 45 if (objStacked && othStacked) { 46 return objStacked == other && othStacked == object; 47 } 48 var result = true; 49 stack.set(object, other); 50 stack.set(other, object); 51 52 var skipCtor = isPartial; 53 while (++index < objLength) { 54 key = objProps[index]; 55 var objValue = object[key], 56 othValue = other[key]; 57 58 if (customizer) { 59 var compared = isPartial 60 ? customizer(othValue, objValue, key, other, object, stack) 61 : customizer(objValue, othValue, key, object, other, stack); 62 } 63 // Recursively compare objects (susceptible to call stack limits). 64 if (!(compared === undefined 65 ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) 66 : compared 67 )) { 68 result = false; 69 break; 70 } 71 skipCtor || (skipCtor = key == 'constructor'); 72 } 73 if (result && !skipCtor) { 74 var objCtor = object.constructor, 75 othCtor = other.constructor; 76 77 // Non `Object` object instances with different constructors are not equal. 78 if (objCtor != othCtor && 79 ('constructor' in object && 'constructor' in other) && 80 !(typeof objCtor == 'function' && objCtor instanceof objCtor && 81 typeof othCtor == 'function' && othCtor instanceof othCtor)) { 82 result = false; 83 } 84 } 85 stack['delete'](object); 86 stack['delete'](other); 87 return result; 88 } 89 90 module.exports = equalObjects;