前言
在做项目优化时,需要用到判断两对象是否一致逻辑,所以自己询着逻辑写了一下,现将它写为文档,以供日后自己查阅
1. 字符串比较
此种情况只适用于两个property顺序完全一致的对象判断
// 1. same order same property
function isObjStringEqual(obj1, obj2) {
return JSON.stringify(obj1) === JSON.stringify(obj2);
}
2. 浅比较
只做第一层数据的查询,跳过数组、对象、方法
利用es6的every函数做最优处理
// 2. shallow compare
function isObjShallowEqual(obj1, obj2) {
const keys1 = Object.getOwnPropertyNames(obj1);
const keys2 = Object.getOwnPropertyNames(obj2);
if (keys1.length !== keys2.length) {
return false;
}
const flag = keys1.every(key => {
const type = typeof obj1[key];
// do not check function, array, object
if (['function', 'array', 'object'].includes(type)) {
return type === typeof obj2[key];
}
// if unequal, return true
if (obj1[key] !== obj2[key]) {
return false;
}
return true;
});
// if found unequal, then return false, which means unequal
return flag;
}
3. 深比较
对array和object做比较,只比较第二层子集,如果array里面再套array或者object,不作处理
// 3. deep compare
function isObjDeepEqual(obj1, obj2) {
const KEY = {
OBJECT: 'object',
ARRAY: 'array',
FUNCTION: 'function',
};
const keys1 = Object.getOwnPropertyNames(obj1);
const keys2 = Object.getOwnPropertyNames(obj2);
if (keys1.length !== keys2.length) {
return false;
}
const flag = keys1.every(key => {
const TYPE = typeof obj1[key];
// escape null && self-call the function
if (!!obj1[key] && TYPE === KEY.OBJECT) {
return isObjDeepEqual(obj1[key], obj2[key]); // the recursion of funciton call
}
// array's case
if (TYPE === KEY.ARRAY) {
// check the length
if (obj1[key].length !== obj2[key].length) {
return false;
}
return obj1[key].every((child, index) => {
const CHILD_TYPE = typeof child;
// skip more deep compare, limit to 2
if ([KEY.ARRAY].includes(CHILD_TYPE)) {
return true;
}
// if function or object, then self-call
if ([KEY.OBJECT, KEY.FUNCTION].includes(CHILD_TYPE)) {
const OBJ2_CHILD = obj2[key][index];
if (CHILD_TYPE !== typeof OBJ2_CHILD) {
return false;
}
return isObjDeepEqual(child, OBJ2_CHILD);
}
// Normal value check
if (child !== obj2[key][index]) {
return false;
}
return true;
});
}
// convert function to string, then compare the value
if (TYPE === KEY.FUNCTION) {
return obj1[key].toString() === obj2[key].toString();
}
// if unequal, return true
if (obj1[key] !== obj2[key]) {
return false;
}
return true;
});
// if found unequal, then return
return flag;
}