deepEqual中傳入第一個對象和第二個對象,返回值為true為完全相等,false為不相等
/**
* 用來判斷一個對象是否是某種類型的靜態(tài)類
*/
export const ObjType = {
isObject(obj) {
return getObjType(obj) === "Object";
},
isArray(obj) {
return getObjType(obj) === "Array";
},
isString(obj) {
return getObjType(obj) === "String";
},
isNumber(obj) {
return getObjType(obj) === "Number";
},
isBoolean(obj) {
return getObjType(obj) === "Boolean";
},
isSymbol(obj) {
return getObjType(obj) === "Symbol";
},
isFunction(obj) {
return getObjType(obj) === "Function";
},
isNull(obj) {
return getObjType(obj) === "Null";
},
isUndefined(obj) {
return getObjType(obj) === "Undefined";
},
isFormData(obj) {
return getObjType(obj) === "FormData";
},
isFile(obj) {
return getObjType(obj) === "File";
}
};
/**
* 對象的深度相等比較,不考慮指針,只比較值
* 需要特別注意的是,比較之前已經(jīng)對數(shù)據(jù)進(jìn)行了深度trim處理
* @param {*} obj 第一個對象
* @param {*} obj2 第二個對象
*/
export function deepEqual(obj, obj2) {
obj = deepTrim(obj);
obj2 = deepTrim(obj2);
return _deepEqual(obj, obj2);
function _deepEqual(obj, obj2) {
if (getObjType(obj) !== getObjType(obj2)) {
return false;
}
if (ObjType.isObject(obj)) {
const keys1 = Object.keys(obj);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) {
return false;
}
return keys1.every(key => {
return _deepEqual(obj[key], obj2[key]);
});
} else if (ObjType.isArray(obj)) {
if (obj.length !== obj2.length) {
return false;
}
return obj.every((item, i) => {
return _deepEqual(obj[i], obj2[i]);
});
} else if (ObjType.isFormData(obj)) {
const arr1 = [...obj];
const arr2 = [...obj2];
if (arr1.length !== arr2.length) {
return false;
}
return arr1.every((kv, idx) => {
const [k1, v1] = arr1[idx];
const [k2, v2] = arr2[idx];
if (k1 !== k2) {
return false;
}
if (getObjType(v1) !== getObjType(v2)) {
return false;
}
if (ObjType.isFile(v1)) {
const keys = ["name", "size", "type"];
return keys.every(key => {
return v1[key] === v2[key];
});
} else {
return v1 === v2;
}
});
} else {
return obj === obj2;
}
}
}
/**
* 對對象進(jìn)行深層trim
*/
export function deepTrim(data) {
return _deepTrim(data);
function _deepTrim(data) {
if (ObjType.isFormData(data)) {
const formData = new FormData();
const iterator = data.entries();
const items = [];
// eslint-disable-next-line no-constant-condition
while (true) {
const { value, done } = iterator.next();
if (done) {
break;
}
const name = value[0];
let val = value[1];
if (ObjType.isString(val)) {
val = val.trim();
}
items.push([name, val]);
}
items.forEach(item => {
const [name, val] = item;
formData.append(name, val);
});
return formData;
} else if (ObjType.isObject(data) || ObjType.isArray(data)) {
const obj = ObjType.isObject(data) ? {} : [];
for (const i in data) {
obj[i] = _deepTrim(data[i]);
}
return obj;
} else if (ObjType.isString(data)) {
return data.trim();
} else {
return data;
}
}
}
/**
* 獲取元素類型,比如數(shù)組是Array,對象是Object,字符串是String
* @param {*} obj
* @returns {string}
*/
export function getObjType(obj) {
const typeStr = Object.prototype.toString.call(obj);
return typeStr.replace(/\[object (\w+)\]/, "$1");
}