vue 源碼 學習days8-比較兩個對象的方法

// 在面試中可能會遇到, 思想重要
// 比較兩個對象是不是相等的 兩個對象
// 1. js 中對象是沒法使用 == 來比較的, 比是地址
// 2. 咱們通常會定義若是對象的各個屬性值都相等 那麼對象就是相等的對象. 例如: {} 就與 {} 相等.
// 算法描述
// 1. 假定對象 a 和 b
// 2. 遍歷 a 中的成員, 判斷是否每個 a 中的成員都在 b 中. 而且 與 b 中的對應成員相等.
// 3. 再遍歷 b 中的成員, 判斷是否每個 b 中的成員都在 a 中. 而且 與 a 中的對應成員相等.
// 4. 若是成員是引用類型, 遞歸.

// 抽象一下, 判斷兩個集合是否相等

/**
 * Check if two values are loosely equal - that is,
 * if they are plain objects, do they have the same shape?
 */
function looseEqual (a: any, b: any): boolean {
  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]) // b 包含 a
        })
      } else if (a instanceof Date && b instanceof Date) {
        return a.getTime() === b.getTime() // 單獨處理 Date 類型, 時間戳應該是同樣的
      } else if ( 0 ) {
        // 若是須要考慮其它類型, 添加 if 便可
      } else if (!isArrayA && !isArrayB) {
        const keysA = Object.keys(a)
        const keysB = Object.keys(b)
        // 先判斷 key 的長度, 再判斷 a 包含於 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
  }
}
相關文章
相關標籤/搜索