vue 原始碼 學習days8-比較兩個物件的方法
阿新 • • 發佈:2020-01-06
// 在面試中可能會遇到, 思想重要
// 比較兩個物件是否是相等的 兩個物件
// 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 } }
// 抽象一下, 判斷兩個集合是否相等
/** * 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 } }