91 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| var getAllKeys = require('./_getAllKeys');
 | |
| 
 | |
| /** Used to compose bitmasks for value comparisons. */
 | |
| var COMPARE_PARTIAL_FLAG = 1;
 | |
| 
 | |
| /** Used for built-in method references. */
 | |
| var objectProto = Object.prototype;
 | |
| 
 | |
| /** Used to check objects for own properties. */
 | |
| var hasOwnProperty = objectProto.hasOwnProperty;
 | |
| 
 | |
| /**
 | |
|  * A specialized version of `baseIsEqualDeep` for objects with support for
 | |
|  * partial deep comparisons.
 | |
|  *
 | |
|  * @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 equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
 | |
|   var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
 | |
|       objProps = getAllKeys(object),
 | |
|       objLength = objProps.length,
 | |
|       othProps = getAllKeys(other),
 | |
|       othLength = othProps.length;
 | |
| 
 | |
|   if (objLength != othLength && !isPartial) {
 | |
|     return false;
 | |
|   }
 | |
|   var index = objLength;
 | |
|   while (index--) {
 | |
|     var key = objProps[index];
 | |
|     if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
 | |
|       return false;
 | |
|     }
 | |
|   }
 | |
|   // Check that cyclic values are equal.
 | |
|   var objStacked = stack.get(object);
 | |
|   var othStacked = stack.get(other);
 | |
|   if (objStacked && othStacked) {
 | |
|     return objStacked == other && othStacked == object;
 | |
|   }
 | |
|   var result = true;
 | |
|   stack.set(object, other);
 | |
|   stack.set(other, object);
 | |
| 
 | |
|   var skipCtor = isPartial;
 | |
|   while (++index < objLength) {
 | |
|     key = objProps[index];
 | |
|     var objValue = object[key],
 | |
|         othValue = other[key];
 | |
| 
 | |
|     if (customizer) {
 | |
|       var compared = isPartial
 | |
|         ? customizer(othValue, objValue, key, other, object, stack)
 | |
|         : customizer(objValue, othValue, key, object, other, stack);
 | |
|     }
 | |
|     // Recursively compare objects (susceptible to call stack limits).
 | |
|     if (!(compared === undefined
 | |
|           ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
 | |
|           : compared
 | |
|         )) {
 | |
|       result = false;
 | |
|       break;
 | |
|     }
 | |
|     skipCtor || (skipCtor = key == 'constructor');
 | |
|   }
 | |
|   if (result && !skipCtor) {
 | |
|     var objCtor = object.constructor,
 | |
|         othCtor = other.constructor;
 | |
| 
 | |
|     // Non `Object` object instances with different constructors are not equal.
 | |
|     if (objCtor != othCtor &&
 | |
|         ('constructor' in object && 'constructor' in other) &&
 | |
|         !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
 | |
|           typeof othCtor == 'function' && othCtor instanceof othCtor)) {
 | |
|       result = false;
 | |
|     }
 | |
|   }
 | |
|   stack['delete'](object);
 | |
|   stack['delete'](other);
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| module.exports = equalObjects;
 |