# 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 的「只填充缺失鍵」行為
