UNPKG

deepmerge-plus

Version:

用於深度(遞迴)合併 JavaScript 物件的函式庫 / A library for deep (recursive) merging of JavaScript objects

193 lines (149 loc) 5.27 kB
# deepmerge 與 lodash 函式比較 # deepmerge vs Lodash Function Comparison --- ## 測試結果總覽 / Test Results Overview | Lodash 函式 | deepmerge 對應方式 | 結果 | 說明 | |------------|------------------|------|------| | `_.assign` | 直接使用 deepmerge | isEqual: true | 淺層合併行為一致 | | `_.assign` (多來源) | 使用 deepmergeAll | isEqual: true | 多物件依序合併 | | `_.merge` | 直接使用 deepmerge | isEqual: true | 深度合併行為一致 | | `_.merge` (陣列) | deepmerge 預設 | ⚠️ isEqual: false | deepmerge 串接,lodash 替換 | | `_.merge` (陣列) | 自訂 arrayMerge | isEqual: false | 無法完全模擬 lodash 行為 | | `_.defaults` | keyValueOrMode: true | ⚠️ isEqual: false | keyValueOrMode 只影響巢狀物件,不影響根層級 | | `_.defaultsDeep` | keyValueOrMode: true | isEqual: false | 嘗試 1 - 仍覆蓋現有屬性 | | `_.defaultsDeep` | isMergeableObject: false | isEqual: false | 嘗試 2 - 導致整體覆蓋 | | `_.defaultsDeep` | keyValueOrMode + arrayMerge | isEqual: false | 嘗試 3 - 無法模擬 | --- ## 詳細比較 / Detailed Comparison ### 1. _.assign 等價 / Equivalent ```typescript // deepmerge const result = deepmerge({ a: 1, b: 2 }, { b: 3, c: 4 }); // 結果 / Result: { a: 1, b: 3, c: 4 } // lodash const result = _.assign({}, { a: 1, b: 2 }, { b: 3, c: 4 }); // 結果 / Result: { a: 1, b: 3, c: 4 } ``` **結論 / Conclusion**: 完全相同 / Identical --- ### 2. _.merge 等價 / Equivalent ```typescript // deepmerge const result = deepmerge( { a: 1, b: { c: 2, d: 3 } }, { b: { d: 4, e: 5 }, f: 6 } ); // 結果 / Result: { a: 1, b: { c: 2, d: 4, e: 5 }, f: 6 } // lodash const result = _.merge( {}, { a: 1, b: { c: 2, d: 3 } }, { b: { d: 4, e: 5 }, f: 6 } ); // 結果 / Result: { a: 1, b: { c: 2, d: 4, e: 5 }, f: 6 } ``` **結論 / Conclusion**: 完全相同 / Identical --- ### 3. 陣列處理差異 / Array Handling Difference ```typescript // deepmerge (預設串接 / default concat) const result = deepmerge( { items: [1, 2, 3] }, { items: [4, 5] } ); // 結果 / Result: { items: [1, 2, 3, 4, 5] } // lodash (替換 / replace) const result = _.merge( {}, { items: [1, 2, 3] }, { items: [4, 5] } ); // 結果 / Result: { items: [4, 5, 3] } ``` **結論 / Conclusion**: ⚠️ 不同 / Different **嘗試模擬 / Attempt to simulate**: ```typescript // 使用自訂 arrayMerge const result = deepmerge( { items: [1, 2, 3] }, { items: [4, 5] }, { arrayMerge: (_target, _source) => _source } ); // deepmerge 結果 / deepmerge result: { items: [4, 5] } // lodash 結果 / lodash result: { items: [4, 5, 3] } (保留 target 第三個元素 / keeps target's third element) // 無法完全模擬 / Cannot fully simulate // isEqual: false ``` --- ### 4. _.defaults 差異 / _.defaults Difference ```typescript // deepmerge (keyValueOrMode: true) const result = deepmerge( { a: 1, b: 2 }, { b: 3, c: 4 }, { keyValueOrMode: true } ); // 結果 / Result: { a: 1, b: 3, c: 4 } (b 被覆蓋 / b overwritten) // lodash const result = _.defaults({ a: 1, b: 2 }, { b: 3, c: 4 }); // 結果 / Result: { a: 1, b: 2 } (只添加 c:4 / only adds c:4) ``` **結論 / Conclusion**: ⚠️ 不同 / Different **原因 / Reason**: `keyValueOrMode: true` 只影響巢狀物件,不影響根層級屬性 --- ### 5. _.defaultsDeep 差異 / _.defaultsDeep Difference ```typescript // deepmerge (keyValueOrMode: true) const result = deepmerge( { a: 1, b: { c: 2, d: 3 } }, { b: { d: 4, e: 5 }, f: 6 }, { keyValueOrMode: true } ); // 結果 / Result: { a: 1, b: { c: 2, d: 4, e: 5 }, f: 6 } // lodash const result = _.defaultsDeep({ a: 1, b: { c: 2, d: 3 } }, { b: { d: 4, e: 5 }, f: 6 }); // 結果 / Result: { a: 1, b: { c: 2, d: 3 } } ``` **結論 / Conclusion**: 不同 / Different **嘗試次數 / Attempts**: 1. keyValueOrMode: true - 仍覆蓋現有巢狀屬性 2. isMergeableObject: () => false - 導致整體覆蓋 3. keyValueOrMode + arrayMerge - 無法模擬 **放棄原因 / Give up reason**: lodash _.defaultsDeep 的行為無法透過現有選項完全模擬 --- ## 實作選項參考 / Implementation Options Reference ### 深度合併 (Deep Merge) ```typescript deepmerge(target, source) ``` ### 淺層合併 (Shallow Merge) ```typescript deepmerge(target, source, { isMergeableObject: () => false }) ``` ### 陣列替換 (Array Replace) ```typescript deepmerge(target, source, { arrayMerge: (_target, _source) => _source }) ``` ### 保留目標值 (Preserve Target Values) ```typescript deepmerge(target, source, { keyValueOrMode: true }) ``` --- ## 結論 / Conclusion | 函式 | isEqual | deepmerge 可完全模擬? | |------|---------|----------------------| | `_.assign` | true | 可以 | | `_.assign` (多來源) | true | 可以 | | `_.merge` | true | 可以 | | `_.merge` (陣列) | false | 無法完全模擬 | | `_.defaults` | false | keyValueOrMode 只影響巢狀 | | `_.defaultsDeep` | false | 無法模擬 | **主要差異**: 1. 陣列處理:deepmerge 預設串接,lodash 替換 2. defaults 行為:deepmerge 無法完全模擬 lodash 的「只填充缺失鍵」行為