UNPKG

ut2

Version:

一个现代 JavaScript 实用工具库。[点击查看在线文档]。

179 lines (176 loc) 6.19 kB
import allKeys from '../allKeys.js'; import eq from '../eq.js'; import getTagWithBugfix from './getTagWithBugfix.js'; import { symbolProto, nativeUndefined, arrayBufferTag, dataViewTag, errorTag, symbolTag, regExpTag, stringTag, dateTag, booleanTag, numberTag, objectTag, objectProtoHasOwnProperty, arrayTag, argumentsTag, setTag, mapTag, arrayProtoSlice } from './native.js'; import isBuffer from '../isBuffer.js'; import isFunction from '../isFunction.js'; import isNil from '../isNil.js'; import isObjectLike from '../isObjectLike.js'; import isTypedArray from '../isTypedArray.js'; import orderBy from '../orderBy.js'; var symbolValueOf = symbolProto ? symbolProto.valueOf : nativeUndefined; function mapToArray(map) { var result = []; map.forEach(function (value, key) { result.push([key, value]); }); return orderBy(result, [0, 1]); } function setToArray(set) { var result = []; set.forEach(function (value) { result.push(value); }); return orderBy(result); } function argToArray(arg) { return arrayProtoSlice.call(arg); } function toBufferView(bufferSource) { return new Uint8Array(bufferSource.buffer || bufferSource, bufferSource.byteOffset || 0, bufferSource.byteLength); } function isDomNode(obj) { return isObjectLike(obj) && typeof obj.nodeType === 'number' && typeof obj.nodeName === 'string' && typeof obj.isEqualNode === 'function'; } function isEqualDeep(value, other, customizer, strictCheck, valueStack, otherStack) { if (eq(value, other, strictCheck)) { return true; } var valType = typeof value; var othType = typeof other; if (strictCheck && valType !== othType) { return false; } if (isNil(value) || isNil(other) || (valType !== 'object' && othType !== 'object')) { return false; } var tag = getTagWithBugfix(value); if (tag !== getTagWithBugfix(other)) { return false; } var convert; switch (tag) { case numberTag: return eq(+value, +other, strictCheck); case booleanTag: case dateTag: return strictCheck ? +value === +other : eq(+value, +other); case stringTag: case regExpTag: return '' + value === '' + other; case symbolTag: return symbolValueOf ? symbolValueOf.call(value) === symbolValueOf.call(other) : false; case errorTag: return value.name === other.name && value.message === other.message; case dataViewTag: case arrayBufferTag: if (value.byteLength !== other.byteLength || (value.byteOffset && value.byteOffset !== other.byteOffset)) { return false; } convert = toBufferView; break; case mapTag: convert = mapToArray; break; case setTag: convert = setToArray; break; case argumentsTag: convert = argToArray; break; } if (convert) { return isEqualDeep(convert(value), convert(other), customizer, strictCheck, valueStack, otherStack); } if (isDomNode(value) && isDomNode(other)) { return value.isEqualNode(other); } var areArrays = tag === arrayTag; if (!areArrays && isTypedArray(value)) { if (value.byteLength !== other.byteLength) { return false; } if (value.buffer === other.buffer && value.byteOffset === other.byteOffset) { return true; } areArrays = true; } if (isBuffer(value)) { if (!isBuffer(other)) { return false; } areArrays = true; } valueStack = valueStack || []; otherStack = otherStack || []; var length = valueStack.length; while (length--) { if (valueStack[length] === value) { return otherStack[length] === other; } } valueStack.push(value); otherStack.push(other); var result = true; var hasCustomizer = typeof customizer === 'function'; if (areArrays) { length = value.length; if (length !== other.length) { return false; } while (length--) { if (hasCustomizer) { var compared = customizer(value[length], other[length], length, value, other, valueStack, otherStack); if (compared !== nativeUndefined) { if (!compared) { return false; } continue; } } if (!isEqualDeep(value[length], other[length], customizer, strictCheck, valueStack, otherStack)) { return false; } } } else if (tag === objectTag) { var keys = allKeys(value); length = keys.length; if (allKeys(other).length !== length) { return false; } var skipCtor = false; while (length--) { var key = keys[length]; if (hasCustomizer) { var compared = customizer(value[key], other[key], key, value, other, valueStack, otherStack); if (compared !== nativeUndefined) { if (!compared) { return false; } continue; } } if (!(objectProtoHasOwnProperty.call(other, key) && isEqualDeep(value[key], other[key], customizer, strictCheck, valueStack, otherStack))) { return false; } if (!skipCtor && key === 'constructor') { skipCtor = true; } } if (!skipCtor) { var valCtor = value.constructor; var othCtor = other.constructor; if (valCtor !== othCtor && !(isFunction(valCtor) && valCtor instanceof valCtor && isFunction(othCtor) && othCtor instanceof othCtor) && 'constructor' in value && 'constructor' in other) { return false; } } } else { result = false; } valueStack.pop(); otherStack.pop(); return result; } export { isEqualDeep as default };