1var Symbol = require('./_Symbol'), 2 Uint8Array = require('./_Uint8Array'), 3 eq = require('./eq'), 4 equalArrays = require('./_equalArrays'), 5 mapToArray = require('./_mapToArray'), 6 setToArray = require('./_setToArray'); 7 8/** Used to compose bitmasks for value comparisons. */ 9var COMPARE_PARTIAL_FLAG = 1, 10 COMPARE_UNORDERED_FLAG = 2; 11 12/** `Object#toString` result references. */ 13var boolTag = '[object Boolean]', 14 dateTag = '[object Date]', 15 errorTag = '[object Error]', 16 mapTag = '[object Map]', 17 numberTag = '[object Number]', 18 regexpTag = '[object RegExp]', 19 setTag = '[object Set]', 20 stringTag = '[object String]', 21 symbolTag = '[object Symbol]'; 22 23var arrayBufferTag = '[object ArrayBuffer]', 24 dataViewTag = '[object DataView]'; 25 26/** Used to convert symbols to primitives and strings. */ 27var symbolProto = Symbol ? Symbol.prototype : undefined, 28 symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; 29 30/** 31 * A specialized version of `baseIsEqualDeep` for comparing objects of 32 * the same `toStringTag`. 33 * 34 * **Note:** This function only supports comparing values with tags of 35 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. 36 * 37 * @private 38 * @param {Object} object The object to compare. 39 * @param {Object} other The other object to compare. 40 * @param {string} tag The `toStringTag` of the objects to compare. 41 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. 42 * @param {Function} customizer The function to customize comparisons. 43 * @param {Function} equalFunc The function to determine equivalents of values. 44 * @param {Object} stack Tracks traversed `object` and `other` objects. 45 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. 46 */ 47function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { 48 switch (tag) { 49 case dataViewTag: 50 if ((object.byteLength != other.byteLength) || 51 (object.byteOffset != other.byteOffset)) { 52 return false; 53 } 54 object = object.buffer; 55 other = other.buffer; 56 57 case arrayBufferTag: 58 if ((object.byteLength != other.byteLength) || 59 !equalFunc(new Uint8Array(object), new Uint8Array(other))) { 60 return false; 61 } 62 return true; 63 64 case boolTag: 65 case dateTag: 66 case numberTag: 67 // Coerce booleans to `1` or `0` and dates to milliseconds. 68 // Invalid dates are coerced to `NaN`. 69 return eq(+object, +other); 70 71 case errorTag: 72 return object.name == other.name && object.message == other.message; 73 74 case regexpTag: 75 case stringTag: 76 // Coerce regexes to strings and treat strings, primitives and objects, 77 // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring 78 // for more details. 79 return object == (other + ''); 80 81 case mapTag: 82 var convert = mapToArray; 83 84 case setTag: 85 var isPartial = bitmask & COMPARE_PARTIAL_FLAG; 86 convert || (convert = setToArray); 87 88 if (object.size != other.size && !isPartial) { 89 return false; 90 } 91 // Assume cyclic values are equal. 92 var stacked = stack.get(object); 93 if (stacked) { 94 return stacked == other; 95 } 96 bitmask |= COMPARE_UNORDERED_FLAG; 97 98 // Recursively compare objects (susceptible to call stack limits). 99 stack.set(object, other); 100 var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); 101 stack['delete'](object); 102 return result; 103 104 case symbolTag: 105 if (symbolValueOf) { 106 return symbolValueOf.call(object) == symbolValueOf.call(other); 107 } 108 } 109 return false; 110} 111 112module.exports = equalByTag; 113