zent
Version:
一套前端设计语言和基于React的实现
156 lines (155 loc) • 4.91 kB
JavaScript
import { hasOwnProperty } from './hasOwn';
var toString = Object.prototype.toString;
var valueOfSymbol = Symbol.prototype.valueOf;
var objKeys = Object.keys;
var objIs = Object.is;
export default function isEqual(value, other) {
var stack = [{ type: 'generic', a: value, b: other }];
var aStack = [];
var bStack = [];
while (stack.length > 0) {
var op = stack.pop();
if (op.type === 'generic') {
var a = op.a, b = op.b;
if (objIs(a, b)) {
continue;
}
var type = typeof a;
if (type !== 'function' && type !== 'object' && typeof b !== 'object') {
return false;
}
var tag = toString.call(a);
if (tag !== toString.call(b)) {
return false;
}
if (tag === '[object RegExp]' || tag === '[object String]') {
if ('' + a !== '' + b) {
return false;
}
continue;
}
if (tag === '[object Number]') {
if (!objIs(+a, +b)) {
return false;
}
continue;
}
if (tag === '[object Date]' || tag === '[object Boolean]') {
if (+a !== +b) {
return false;
}
continue;
}
if (tag === '[object Symbol]') {
if (valueOfSymbol.call(a) !== valueOfSymbol.call(b)) {
return false;
}
continue;
}
var areArrays = tag === '[object Array]';
if (!areArrays) {
if (typeof a !== 'object' || typeof b !== 'object') {
return false;
}
var aCtor = a.constructor;
var bCtor = b.constructor;
if (aCtor !== bCtor &&
!(typeof aCtor === 'function' &&
aCtor instanceof aCtor &&
typeof bCtor === 'function' &&
bCtor instanceof bCtor) &&
'constructor' in a &&
'constructor' in b) {
return false;
}
}
var length_1 = aStack.length;
while (length_1--) {
if (aStack[length_1] === a) {
if (bStack[length_1] === b) {
break;
}
return false;
}
}
if (length_1 >= 0) {
continue;
}
aStack.push(a);
bStack.push(b);
stack.push({
type: 'children-done',
});
if (areArrays) {
var len = a.length;
if (len !== b.length) {
return false;
}
if (len === 0) {
continue;
}
stack.push({
type: 'array',
size: len,
index: 0,
a: a,
b: b,
});
}
else if (tag === '[object Object]') {
var keys = objKeys(a);
var len = keys.length;
if (objKeys(b).length !== len) {
return false;
}
if (len === 0) {
continue;
}
stack.push({
type: 'object',
a: a,
b: b,
keys: keys,
size: len,
index: 0,
});
}
else {
throw new Error("isEqual not implemented for " + tag);
}
}
else if (op.type === 'array') {
var a = op.a, b = op.b, size = op.size, index = op.index;
if (index < size - 1) {
op.index++;
stack.push(op);
}
stack.push({
type: 'generic',
a: a[index],
b: b[index],
});
}
else if (op.type === 'object') {
var a = op.a, b = op.b, keys = op.keys, size = op.size, index = op.index;
var k = keys[index];
if (!hasOwnProperty(b, k)) {
return false;
}
if (index < size - 1) {
op.index++;
stack.push(op);
}
stack.push({
type: 'generic',
a: a[k],
b: b[k],
});
}
else if (op.type === 'children-done') {
aStack.pop();
bStack.pop();
}
}
return true;
}