判斷兩個對象的內容是否相等


由於在做鍵盤導航組件的項目時,有這樣一個需求,當用戶傳入按鍵字母和網址的映射時,如果和 localStorage 中的不一樣那么就用 localStorage 中存儲的,這個時候就需要比較兩個對象的內容是否相等,但是在 JS 中對象是一種引用類型.

obj1 = {
  a: 1
}
obj2 = {
  a: 1
}
console.log(obj1 === obj2) // false

即使兩個對象的內容完全相同,因為它們的地址不同,因此 obj1 === obj2 會返回 fasle。

所以自己根據深拷貝時遞歸的思想寫了一個比較兩個對象之間內容是否相同的函數。

function compareObject (obj1, obj2) {
  // 遞歸終止條件,當 obj1 或 obj2 不是對象時,此時就可以進行判斷了
  if (typeof obj1 !== 'object' || typeof obj2 !== 'object') {
    if (obj1 === obj2) {
      return true
    } else if (obj1 !== obj2) {
      return false
    }
  }
  // 獲取對象的自由屬性組成的數組
  const obj1PropsArr = Object.getOwnPropertyNames(obj1)
  const obj2PropsArr = Object.getOwnPropertyNames(obj2) 
  // 如果數組的長度不相等,那么說明對象屬性的個數都不同,返回 false
  if (obj1PropsArr.length !== obj2PropsArr.length) {
    return false
  }
  // 記錄當前 compareObject 的返回值,默認是 true
  let status = true
  for (key of obj1PropsArr) {
    status = compareObject(obj1[key], obj2[key])
    // 關鍵代碼,當 status 為 false 時下面就不用再進行判斷了,說明兩個對象的內容並不相同
    // 如果沒有下面這條語句,那么只要對象底層的內容是相同的那么就返回 true
    if (!status) {
      break
    }
  }
  // 每次 compareObject 執行的返回結果
  return status
}

測試代碼:

// 判斷兩個對象的內容相等
const obj1 = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: 4
    }
  }
}
const obj2 = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: 4
    }
  }
}
console.log(compareObject(obj1, obj2)) // true

// 判斷兩個對象的內容不相等
const obj1 = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: 4
    }
  }
}
const obj2 = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: 5
    }
  }
}
console.log(compareObject(obj1, obj2)) // false

接下來再來強調一下 compareObject 函數中第 23 行這句關鍵代碼,如果沒有這條語句那么最后的返回結果只會取決於兩個對象最底層屬性(最后一次)的比較結果。

if (!status) {
  break
}

例如,我將兩個對象變為下面這樣:

const obj1 = {
  a: 1,
  b: {
    c: 3, // 和 obj2 不相等
    d: {
      e: 4
    }
  }
}
const obj2 = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: 4
    }
  }
}
console.log(compareObject(obj1, obj2)) // true

可以看到最后的返回結果是 true,因為最后的一次比較是 e 屬性,它們的值是相等的。

上面這樣的寫法應該還有一些情況沒有考慮到,對於我的項目需求而言已經足夠了,如果哪位小伙伴發現了希望可以提出來,然后再將它改進一下,非常感謝。


免責聲明!

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



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