js中两个对象的比较
生活随笔
收集整理的這篇文章主要介紹了
js中两个对象的比较
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
代碼取自于underscore.js 1.8.3的isEqual函數。
做了一些小小的修改,主要是Function的比較修改。
自己也加了一些代碼解讀。
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>js中兩個對象的比較</title><script> /* 需求難點描述: 數組和對象,都能包含自身,還能包含其它類型。 所以數組之間的比較,要遞歸。 所以這塊代碼的設計是: 不能包含自身的,先比較。 然后是數組,對象比較。 特別要注意的是,對象的循環引用。 遞歸時,要記錄遞歸的路徑。 */ function isEqual(a, b) {var toString = Object.prototype.toString,object_keys = Object.keys,has = function(obj, key) {return obj != null && hasOwnProperty.call(obj, key);};var isFunction = function(fn){return toString.call(fn) == '[object Function]' ? true : false;}; var eq = function(a, b, aStack, bStack) {// Identical objects are equal. `0 === -0`, but they aren't identical.// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).// 驗證0===-0if (a === b) return a !== 0 || 1 / a === 1 / b;// A strict comparison is necessary because `null == undefined`.// null// 驗證null == undefinedif (a == null || b == null) return a === b;// Compare `[[Class]]` names.var className = toString.call(a);if (className !== toString.call(b)) return false;switch (className) {// Strings, numbers, regular expressions, dates, and booleans are compared by value.case '[object RegExp]':// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')case '[object String]':// function雖然是引用,但兩個內容一樣的funciton應該相等。case '[object Function]':// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is// equivalent to `new String("5")`.return '' + a === '' + b;case '[object Number]':// `NaN`s are equivalent, but non-reflexive.// Object(NaN) is equivalent to NaN// 驗證 NaNif (+a !== +a) return +b !== +b;// An `egal` comparison is performed for other numeric values.return +a === 0 ? 1 / +a === 1 / b : +a === +b;case '[object Date]':case '[object Boolean]':// Coerce dates and booleans to numeric primitive values. Dates are compared by their// millisecond representations. Note that invalid dates with millisecond representations// of `NaN` are not equivalent.return +a === +b;}var areArrays = className === '[object Array]';if (!areArrays) {if (typeof a != 'object' || typeof b != 'object') return false;// Objects with different constructors are not equivalent, but `Object`s or `Array`s// from different frames are.var aCtor = a.constructor,bCtor = b.constructor;// 判斷順序// 構造器一致// 構造器為函數// 擁有構造器屬性// Function instanceof Function == true// Object instanceof Object == true// Array instanceof Array == falseif (aCtor !== bCtor && !(isFunction(aCtor) && aCtor instanceof aCtor &&isFunction(bCtor) && bCtor instanceof bCtor) && ('constructor' in a && 'constructor' in b)) {return false;}}// Assume equality for cyclic structures. The algorithm for detecting cyclic// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.// Initializing stack of traversed objects.// It's done here since we only need them for objects and arrays comparison. aStack = aStack || [];bStack = bStack || [];var length = aStack.length;while (length--) {// 遞歸才會走到這步 // Linear search. Performance is inversely proportional to the number of// unique nested structures.// 檢測循環引用,參考用例如下/*var a = {"str":"string",};a["test"]=a;var b = {"str":"string",};b["test"]=b;console.log (isEqual(a,b));*/if (aStack[length] === a){// 判斷b的引用是否也循環,跳出循環引用這個坑return bStack[length] === b;} }// Add the first object to the stack of traversed objects.// 遞歸壓棧 aStack.push(a);bStack.push(b);// Recursively compare objects and arrays.if (areArrays) {// Compare array lengths to determine if a deep comparison is necessary. length = a.length;// 數組長度比較if (length !== b.length) return false;// Deep compare the contents, ignoring non-numeric properties.// 遞歸比較while (length--) {if (!eq(a[length], b[length], aStack, bStack)) return false;}} else {// Deep compare objects.// 把對象的屬性們轉換成一個數組var keys = object_keys(a),key;length = keys.length;// Ensure that both objects contain the same number of properties before comparing deep equality.if (object_keys(b).length !== length) return false;while (length--) {// Deep compare each member key = keys[length];// b也有a一樣的key,則遞歸if (!(has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;}}// Remove the first object from the stack of traversed objects.// 遞歸出棧 aStack.pop();bStack.pop();return true;};return eq(a,b); }var a = {"str":"ying", }; a["test"]=a;var b = {"str":"ying", }; b["test"]=a;console.log (isEqual(a,b));</script> </head> <body></body> </html>?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的js中两个对象的比较的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle提议将G1作为Java 9的
- 下一篇: /sbin/ifup: configur