如何合併多個物件
方法 1: 使用展開運算子(Spread Operator,...)
這是最現代且簡單的方法,從 ES6 開始支援。適合用在 ES6+ 的環境(如現代瀏覽器或 Babel 轉譯)。它會建立一個新物件,不會修改原物件(淺拷貝)。
步驟:
-
準備多個物件,例如 obj1、obj2、obj3。
-
用大括號 包住,裡面用 ... 展開每個物件。
-
從左到右展開,後面的會覆蓋前面的重複屬性。
-
賦值給一個新變數,避免修改原物件。
完整程式碼範例:
// 準備多個物件
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 的內建方法,也很簡單。它可以一次傳多個來源物件,目標物件會被修改,但我們可以用空物件 當目標來避免修改原物件。
步驟:
-
準備多個物件。
-
用
Object.assign(目標物件, 來源1, 來源2, ...)語法。 -
第一個參數放 當新目標。
-
後面的參數放要合併的物件,從左到右,後面的覆蓋前面的。
-
回傳的是合併後的物件。
完整程式碼範例:
// 準備多個物件
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,或想更了解底層,這是用原生迴圈來合併。適合初學者理解原理,但程式碼較長。
步驟:
-
準備一個空物件當新目標。
-
把要合併的物件放進陣列(方便迴圈)。
-
用 for...in 迴圈遍歷每個物件的屬性。
-
對每個屬性,用目標[key] = value 來賦值(後面的覆蓋前面的)。
-
最後回傳目標物件。
完整程式碼範例:
// 準備多個物件
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() 函式庫,或自己遞迴寫一個函式。