1.

【Metasequoia 】オブジェクトを結合する方法

編集
この記事の要点
  • JavaScript でオブジェクトを結合する 3 つの方法
  • Object.assign(target, ...sources): ES6 から、target を変更する
  • スプレッド構文 { ...a, ...b }: ES2018+ 推奨、新オブジェクトを作る
  • lodash merge / mergeWith: ネストした深いマージが必要なとき
  • 注意: シャローコピー(ネストは参照共有)。深いコピーは structuredClone()

 

方法 1: スプレッド構文(推奨)

ES2018 以降で使える、もっとも読みやすい方法。新しいオブジェクトを返すので元のオブジェクトは変更されません。

const a = { name: "Alice", age: 30 };
const b = { age: 31, email: "alice@example.com" };

const merged = { ...a, ...b };
console.log(merged);
// → { name: "Alice", age: 31, email: "alice@example.com" }
// 後の方 (b の age) が優先される

// 3 つ以上
const c = { role: "admin" };
const all = { ...a, ...b, ...c };

// プロパティを追加・上書き
const updated = { ...a, age: 35, status: "active" };

// 元のオブジェクトを保持したまま部分更新(イミュータブル)
const user = { name: "Alice", profile: { age: 30 } };
const newUser = { ...user, name: "Bob" };  // user は変わらない

方法 2: Object.assign()

ES6 (ES2015) から。第 1 引数 (target) を変更するので注意。

const a = { name: "Alice", age: 30 };
const b = { age: 31, email: "alice@example.com" };

const merged = Object.assign(a, b);
console.log(a);
// → { name: "Alice", age: 31, email: "alice@example.com" }
// a が変更される!

// a を変更したくない場合は空オブジェクトを target に
const merged2 = Object.assign({}, a, b);
console.log(a);  // → 変わらない
console.log(merged2);  // → { name: "Alice", age: 31, email: "..." }

方法 3: lodash の merge / mergeWith(深いマージ)

ネストされたオブジェクトを再帰的にマージしたいとき:

const a = {
  name: "Alice",
  profile: { age: 30, hobbies: ["read"] }
};
const b = {
  profile: { age: 31, location: "Tokyo" }
};

// スプレッドの場合(シャロー)
const shallow = { ...a, ...b };
console.log(shallow.profile);
// → { age: 31, location: "Tokyo" }
// hobbies が消える!b の profile が a の profile を完全に上書き

// lodash の merge
import _ from "lodash";
const deep = _.merge({}, a, b);
console.log(deep.profile);
// → { age: 31, hobbies: ["read"], location: "Tokyo" }
// ネストもマージされる

シャローコピー vs ディープコピー

スプレッド・Object.assign は1 階層だけのコピーです:

const a = { profile: { age: 30 } };
const b = { ...a };

b.profile.age = 99;
console.log(a.profile.age);  // → 99
// a.profile と b.profile は同じオブジェクトを参照(シャローコピー)

// ディープコピーの方法
// 1. structuredClone (モダンブラウザ + Node 17+)
const deep = structuredClone(a);

// 2. JSON 経由(関数・Date 等は失われる)
const deep2 = JSON.parse(JSON.stringify(a));

// 3. lodash の cloneDeep
const deep3 = _.cloneDeep(a);

deep.profile.age = 99;
console.log(a.profile.age);  // → 30 (変わらない)

条件付きマージ

// 条件で対象を変える
const base = { name: "Alice" };
const extra = condition ? { extra: "value" } : {};
const result = { ...base, ...extra };

// null / undefined はマージしても OK (空オブジェクト相当)
const merged = { ...base, ...null, ...undefined };  // base そのまま

// 条件で property を含める / 除外
const user = {
  name: "Alice",
  ...(isAdmin && { role: "admin" }),
  ...(email && { email })
};

配列のマージ

オブジェクトとは別:

const a = [1, 2, 3];
const b = [4, 5, 6];

// スプレッド
const merged = [...a, ...b];  // → [1,2,3,4,5,6]

// concat
const merged2 = a.concat(b);   // → [1,2,3,4,5,6]

// 重複排除
const unique = [...new Set([...a, ...b])];

// オブジェクトの配列を ID でマージ
const users1 = [{ id: 1, name: "A" }, { id: 2, name: "B" }];
const users2 = [{ id: 2, name: "B2" }, { id: 3, name: "C" }];

const merged3 = [...new Map(
  [...users1, ...users2].map(u => [u.id, u])
).values()];
// → [{id:1,name:"A"}, {id:2,name:"B2"}, {id:3,name:"C"}]

注意点

方法シャロー / ディープ元を変更備考
スプレッド {...a, ...b}シャロー×推奨
Object.assign(a, b)シャロー○(a を変更)第 1 引数注意
Object.assign({}, a, b)シャロー×スプレッドと同等
_.merge({}, a, b)ディープ×lodash 依存
structuredClone(a)ディープコピー×マージはしない、単純コピー
JSON.parse(JSON.stringify(a))ディープ×関数/Date/undefined 喪失

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ

同階層のページはありません