### 在 JavaScript 中如何比較兩個對象?
#### Answer
即使兩個不同的對象擁有相同的屬性和相同的值,它們使用`==`和`===`比較的時候也不會被認為是相等的。這是因為它們是通過它們的引用來比較的(也就是在內存中的地址),而與簡單值不同是通過值得比較。
為了測試是否兩個對象在結構上是一樣的,需要一個助手函數。它會遍歷每一個對象的自身屬性去測試是否它們擁有相等的值,包含了嵌套對象。
可選的,對象的prototype也可以被測試是否相等通過傳遞第三個參數為`true`。
提示:此技術只能用來測試簡單對象,數組,函數,時間對象和簡單值是否結構相等。
function isDeepEqual(obj1, obj2, testPrototypes = false) { if (obj1 === obj2) {//如果obj1和obj2是同一個對象,返回true return true } if (typeof obj1 === "function" && typeof obj2 === "function") { //如果obj1和obj2都是function,轉換成字符串后比較 return obj1.toString() === obj2.toString() } if (obj1 instanceof Date && obj2 instanceof Date) { //如果obj1和obj2都是Date實例,獲取毫秒值比較 return obj1.getTime() === obj2.getTime() } if ( Object.prototype.toString.call(obj1) !== Object.prototype.toString.call(obj2) || typeof obj1 !== "object" ) { return false } //如果obj1是簡單類型且toString后的值不相等,直接返回false const prototypesAreEqual = testPrototypes ? isDeepEqual( Object.getPrototypeOf(obj1), Object.getPrototypeOf(obj2), true ) : true //判斷原型是否相等 const obj1Props = Object.getOwnPropertyNames(obj1) const obj2Props = Object.getOwnPropertyNames(obj2) return ( obj1Props.length === obj2Props.length && prototypesAreEqual && obj1Props.every(prop => isDeepEqual(obj1[prop], obj2[prop])) ) //obj1和obj2自身屬性長度相等 //原型相等 //遞歸調用isDeepEqual判斷每一個屬性值是否相等 }
#### Good to hear
* 簡單值例如字符串和數字比較值就可以了
* 對象比較的時候比較的是引用(就是內存地址)