比較兩個對象是否徹底同樣;具體思路以下: spa
1. 先判斷2個對象的數據類型是否一致。prototype
2. 若是對象的數據是基礎的數據類型; 直接比較; 若是是 Number, 對NaN進行特殊處理。code
3. 若是對象的數據類型是 Array; 對象進行循環, 逐值進行判斷。對象
4. 若是對象的數據類型是 Object; 分別對象的key, value 進行判斷。blog
5. 若是對象的數據類型是 Map 或者 Set; 轉化爲Array進行判斷。get
具體代碼以下string
/** * * 返回對相應的數據類型 */ function getType(data) { return Object.prototype.toString.call(data).substring(8).split(/]/)[0] } /** * * @param {*} sourceObj * @param {*} compareObj * * 比較對象是否相等 * */ function comparisonObject(sourceObj, compareObj) { if (arguments.length < 2) throw "Incorrect number of parameters"; let sourceType = getType(sourceObj); if (sourceType !== getType(compareObj)) return false; // Not objects and arrays if (sourceType !== "Array" && sourceType !== "Object" && sourceType !== "Set" && sourceType !== "Map") { if (sourceType === "Number" && sourceObj.toString() === "NaN") { return compareObj.toString() === "NaN" } if (sourceType === "Date" || sourceType === "RegExp") { return sourceObj.toString() === compareObj.toString() } return sourceObj === compareObj } else if (sourceType === "Array") { if (sourceObj.length !== compareObj.length) return false; if (sourceObj.length === 0) return true; for (let i = 0; i < sourceObj.length; i++) { if (!comparisonObject(sourceObj[i], compareObj[i])) return false; } } else if (sourceType === "Object") { let sourceKeyList = Reflect.ownKeys(sourceObj); let compareKeyList = Reflect.ownKeys(compareObj); let key; if (sourceKeyList.length !== compareKeyList.length) return false; for (let i = 0; i < sourceKeyList.length; i++) { key = sourceKeyList[i]; if (key !== compareKeyList[i]) return false; if (!comparisonObject(sourceObj[key], compareObj[key])) return false; } } else if (sourceType === "Set" || sourceType === "Map") { // 把 Set Map 轉爲 Array if (!comparisonObject(Array.from(sourceObj), Array.from(compareObj))) return false; } return true; }