javascript的對象內容對比


 

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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM