Skip to main content

如何合併多個物件

方法 1: 使用展開運算子(Spread Operator,...)

這是最現代且簡單的方法,從 ES6 開始支援。適合用在 ES6+ 的環境(如現代瀏覽器或 Babel 轉譯)。它會建立一個新物件,不會修改原物件(淺拷貝)。

步驟:

  1. 準備多個物件,例如 obj1、obj2、obj3。

  2. 用大括號 包住,裡面用 ... 展開每個物件。

  3. 從左到右展開,後面的會覆蓋前面的重複屬性。

  4. 賦值給一個新變數,避免修改原物件。

完整程式碼範例:

// 準備多個物件
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 }; // 注意 b 屬性會覆蓋 obj1 的
const obj3 = { d: 5, e: 6 };

// 合併成新物件
const mergedObj = { ...obj1, ...obj2, ...obj3 };

// 印出來看結果
console.log(mergedObj); // 輸出: { a: 1, b: 3, c: 4, d: 5, e: 6 }

解釋:

  • ...obj1 會把 obj1 的所有屬性展開到新物件中。

  • 接著 ...obj2 會加進去,如果有重複(如 b),obj2 的值會覆蓋。

  • 同樣加 ...obj3。

  • 優點:程式碼短、易讀。不會修改原物件。

  • 注意:這是淺合併,如果物件裡有巢狀物件,重複時只覆蓋第一層。

方法 2: 使用 Object.assign() 方法

這是 ES6 的內建方法,也很簡單。它可以一次傳多個來源物件,目標物件會被修改,但我們可以用空物件 當目標來避免修改原物件。

步驟:

  1. 準備多個物件。

  2. Object.assign(目標物件, 來源1, 來源2, ...) 語法。

  3. 第一個參數放 當新目標。

  4. 後面的參數放要合併的物件,從左到右,後面的覆蓋前面的。

  5. 回傳的是合併後的物件。

完整程式碼範例:

// 準備多個物件
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 }; // 注意 b 屬性會覆蓋 obj1 的
const obj3 = { d: 5, e: 6 };

// 合併成新物件(用 {} 當目標,避免修改原物件)
const mergedObj = Object.assign({}, obj1, obj2, obj3);

// 印出來看結果
console.log(mergedObj); // 輸出: { a: 1, b: 3, c: 4, d: 5, e: 6 }

解釋:

  • Object.assign({}, obj1, obj2, obj3) 第一個 是目標,後面是來源。

  • 它會把 obj1 的屬性拷貝到目標,然後 obj2 再加進去(覆蓋重複),最後 obj3。

  • 優點:支援多個物件,瀏覽器相容性好(IE 不支援,但可以用 polyfill)。

  • 注意:和展開運算子一樣,是淺合併。如果目標不是 ,原目標會被修改。

方法 3: 使用手動迴圈合併(用 for...in 迴圈)

如果你的環境是舊版 JavaScript,或想更了解底層,這是用原生迴圈來合併。適合初學者理解原理,但程式碼較長。

步驟:

  1. 準備一個空物件當新目標。

  2. 把要合併的物件放進陣列(方便迴圈)。

  3. 用 for...in 迴圈遍歷每個物件的屬性。

  4. 對每個屬性,用目標[key] = value 來賦值(後面的覆蓋前面的)。

  5. 最後回傳目標物件。

完整程式碼範例:

// 準備多個物件
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 }; // 注意 b 屬性會覆蓋 obj1 的
const obj3 = { d: 5, e: 6 };

// 把物件放進陣列,方便迴圈
const objectsToMerge = [obj1, obj2, obj3];

// 建立空的新物件當目標
const mergedObj = {};

// 用 for...of 迴圈遍歷陣列(或用 for 迴圈也行)
for (let obj of objectsToMerge) {
// 用 for...in 遍歷每個物件的屬性
for (let key in obj) {
// 檢查屬性是否屬於物件本身(避免原型鏈)
if (obj.hasOwnProperty(key)) {
// 賦值到目標,後面的會覆蓋前面的
mergedObj[key] = obj[key];
}
}
}

// 印出來看結果
console.log(mergedObj); // 輸出: { a: 1, b: 3, c: 4, d: 5, e: 6 }

解釋:

  • 先把物件陣列化,然後雙層迴圈:外層遍歷物件,內層遍歷屬性。

  • hasOwnProperty(key) 是為了確保只處理物件自己的屬性,不是繼承的。

  • 優點:完全不用內建方法,懂原理。缺點:程式碼長,不適合生產環境。

  • 注意:一樣是淺合併。如果你有巢狀物件,想深合併,可以用 JSON.parse(JSON.stringify()) 但那會有問題(不處理函式或 undefined)。

比較這三個方法

方法優點缺點適合情境
展開運算子 (...)程式碼最短、易讀ES6+ 環境,瀏覽器舊版需轉譯現代前端專案(如 React)
Object.assign()內建、支援多物件淺合併,IE 不支援一般 JavaScript,需相容性
手動迴圈懂原理,不依賴內建程式碼長、易錯學習或舊環境

記住,這些方法都是淺合併(shallow merge),如果物件有巢狀結構(如 { user: { name: 'John' } }),重複時只覆蓋整個巢狀物件。如果你需要深合併(deep merge),可以考慮用 lodash 的 _.merge() 函式庫,或自己遞迴寫一個函式。