vue是這樣對比的
function looseEqual (a, b) {
if (a === b) return true
const isObjectA = isObject(a)
const isObjectB = isObject(b)
if (isObjectA && isObjectB) {
try {
const isArrayA = Array.isArray(a)
const isArrayB = Array.isArray(b)
if (isArrayA && isArrayB) {
return a.length === b.length && a.every((e, i) => {
return looseEqual(e, b[i])
})
} else if (a instanceof Date && b instanceof Date) {
return a.getTime() === b.getTime()
} else if (!isArrayA && !isArrayB) {
const keysA = Object.keys(a)
const keysB = Object.keys(b)
return keysA.length === keysB.length && keysA.every(key => {
return looseEqual(a[key], b[key])
})
} else {
/* istanbul ignore next */
return false
}
} catch (e) {
/* istanbul ignore next */
return false
}
} else if (!isObjectA && !isObjectB) {
return String(a) === String(b)
} else {
return false
}
}
function isObject (obj) {
return obj !== null && typeof obj === 'object'
}
原生js是這樣對比的
function ObjectContrast(objA,objB){
let flag = true
for(let i in objA){
if(Date.prototype.isPrototypeOf(objA[i]) || Date.prototype.isPrototypeOf(objB[i])){
objA[i] = new Date(objA[i]).Format("yyyy-MM-dd");
objB[i] = new Date(objB[i]).Format("yyyy-MM-dd");
}
if(Array.prototype.isPrototypeOf(objA[i]) || Array.prototype.isPrototypeOf(objB[i])){
continue;
}
if(objA[i] != objB[i]){
flag = false
}
}
return flag
}
//除此之外ObjectContrast也可以傳第三個參數(數組)為規定,驗證兩個對象那些屬性需要作對比,
//在其for循環內,首先驗證數組是否為空(如果為空則比對全部),如果不為空,再驗證 i 是否存在於這個數組(數組.indexOf(i))
//如果存在,再進行對比。
原生js還有這樣對比的
function ObjectContrast(objA,objB){
let ObjectA = Object.keys(objA);
let ObjectB = Object.keys(objB);
if(ObjectA.length !== ObjectB.length){
return false;
}else if(ObjectA.length ===0&& ObjectB.length===0){
return true;
}else{
return !ObjectA.some((v,i)=>{
return ObjectA[v] !== ObjectB[v]
})
}
}
這里還有一些別的有意思的方法
1、數組對比:https://www.cnblogs.com/kukudelaomao/p/7093181.html
JS怎么比較兩個數組是否有完全相同的元素?
Javascript不能直接用==或者===來判斷兩個數組是否相等,無論是相等還是全等都不行,以下兩行JS代碼都會返回false
<script type="text/javascript"> alert([]==[]); alert([]===[]); </script>
要判斷JS中的兩個數組是否相同,需要先將數組轉換為字符串,再作比較。以下兩行代碼將返回true
<script type="text/javascript"> alert([].toString()== [].toString()); alert([].toString()===[].toString()); </script>
JS要比較兩個數組是否有相同的元素,即兩個數組所有元素都相同,但元素的順序不一定一致。只就需要先將數組進行排序,再比較兩個數組是否相等。
試比較以下兩行代碼:
<script type="text/javascript"> alert([1,2,3].toString()== [3,2,1].toString()); alert([1,2,3].sort().toString()== [3,2,1].sort().toString()); </script>
2、對象對比:https://www.jianshu.com/p/90ed8b728975
① 方法一:通過JSON.stringfy(obj)
來判斷兩個對象轉后的字符串是否相等
優點:用法簡單,對於順序相同的兩個對象可以快速進行比較得到結果
缺點:這種方法有限制就是當兩個對比的對象中key的順序不是完全相同時會比較出錯
② 方法二:
// 對Object擴展一個方法chargeObjectEqual Object.prototype.chargeObjectEqual = function(obj){ // 當前Object對象 var propsCurr = Object.getOwnPropertyNames(this); // 要比較的另外一個Object對象 var propsCompare = Object.getOwnPropertyNames(obj); if (propsCurr.length != propsCompare.length) { return false; } for (var i = 0,max = propsCurr.length; i < max; i++) { var propName = propsCurr[i]; if (this[propName] !== obj[propName]) { return false; } } return true; }
getOwnPropertyNames
該方法可以將Object對象的第一層key獲取到並返回一個由第一層key組成的數組。
優點:相對方法一進行了優化,可以應對不同順序的Object進行比較,不用擔心順序不同而對比出錯
缺點:從方法中可以看到只能獲取到第一層的key組成的數組,當對象是復合對象時無法進行多層對象的比較
③ 方法三:
function deepCompare(x, y) { var i, l, leftChain, rightChain; function compare2Objects(x, y) { var p; // remember that NaN === NaN returns false // and isNaN(undefined) returns true if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') { return true; } // Compare primitives and functions. // Check if both arguments link to the same object. // Especially useful on the step where we compare prototypes if (x === y) { return true; } // Works in case when functions are created in constructor. // Comparing dates is a common scenario. Another built-ins? // We can even handle functions passed across iframes if ((typeof x === 'function' && typeof y === 'function') || (x instanceof Date && y instanceof Date) || (x instanceof RegExp && y instanceof RegExp) || (x instanceof String && y instanceof String) || (x instanceof Number && y instanceof Number)) { return x.toString() === y.toString(); } // At last checking prototypes as good as we can if (!(x instanceof Object && y instanceof Object)) { return false; } if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) { return false; } if (x.constructor !== y.constructor) { return false; } if (x.prototype !== y.prototype) { return false; } // Check for infinitive linking loops if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) { return false; } // Quick checking of one object being a subset of another. // todo: cache the structure of arguments[0] for performance for (p in y) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } } for (p in x) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } switch (typeof(x[p])) { case 'object': case 'function': leftChain.push(x); rightChain.push(y); if (!compare2Objects(x[p], y[p])) { return false; } leftChain.pop(); rightChain.pop(); break; default: if (x[p] !== y[p]) { return false; } break; } } return true; } if (arguments.length < 1) { return true; //Die silently? Don't know how to handle such case, please help... // throw "Need two or more arguments to compare"; } for (i = 1, l = arguments.length; i < l; i++) { leftChain = []; //Todo: this can be cached rightChain = []; if (!compare2Objects(arguments[0], arguments[i])) { return false; } } return true; }
深度對比兩個對象是否完全相等,可以封裝成一個組件方便隨時調用。
作者:木A木
鏈接:https://www.jianshu.com/p/90ed8b728975
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。