JavaScript オブジェクトの結合方法
スプレッド演算子 (ES6 以降)
スプレッド演算子 (...) を使うと、オブジェクトを展開して新しいオブジェクトを作成できます。
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj); // 出力: { a: 1, b: 2, c: 3, d: 4 }
- 新しいオブジェクトが作成されるため、元のオブジェクトは変更されません。
- 後ろのオブジェクトのプロパティが前のオブジェクトのプロパティを上書きします。
Object.assign() メソッド
Object.assign() メソッドは、複数のオブジェクトのプロパティをターゲットオブジェクトにコピーします。
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const targetObj = {};
Object.assign(targetObj, obj1, obj2);
console.log(targetObj); // 出力: { a: 1, b: 2, c: 3, d: 4 }
- ターゲットオブジェクトが変更されます。
注意点
- 深いコピーが必要な場合は、専用の関数やライブラリを使う必要があります。
- スプレッド演算子と Object.assign() はどちらもシャローコピーを行います。つまり、オブジェクト内のネストされたオブジェクトはコピーされず、元のオブジェクトを参照します。
どちらを使うべきか
- 既存のオブジェクトを変更したい場合は、Object.assign() を使用します。
- 新しいオブジェクトを作成したい場合は、スプレッド演算子を使用します。
どちらの方法も、オブジェクトの構造が複雑な場合や、パフォーマンスが重要な場合は注意が必要です。
さらに深く理解したい場合
- スプレッド演算子
ES6 の新機能として、多くの記事やチュートリアルで解説されています。 - MDN Web Docs
Object.assign() についての詳細な説明があります。
JavaScript オブジェクトの結合の具体的なコード例と解説
スプレッド演算子を使った結合
// オブジェクトを定義
const person = {
name: '太郎',
age: 30
};
const address = {
city: '東京',
postalCode: '123-4567'
};
// スプレッド演算子を使って結合
const personInfo = { ...person, ...address };
console.log(personInfo); // 出力: { name: '太郎', age: 30, city: '東京', postalCode: '123-4567' }
解説
- 同じキーが存在する場合、後のオブジェクトのプロパティが優先されます(上書きされます)。
- 展開されたプロパティが新しいオブジェクト
personInfo
にコピーされます。 ...person
や...address
の部分が、それぞれのオブジェクトを展開しています。
// オブジェクトを定義
const person = {
name: '次郎',
age: 25
};
const address = {
city: '大阪',
postalCode: '543-2108'
};
// 空のオブジェクトをターゲットとして指定
const personInfo = {};
Object.assign(personInfo, person, address);
console.log(personInfo); // 出力: { name: '次郎', age: 25, city: '大阪', postalCode: '543-2108' }
- 各オブジェクトのプロパティがターゲットオブジェクトにコピーされます。
- 第二引数以降に結合したいオブジェクトを並べます。
Object.assign()
の第一引数にターゲットとなるオブジェクトを指定します。
深いコピーについて
上記の例では、オブジェクトのプロパティが単純な値(文字列、数値など)の場合に有効です。しかし、プロパティ自体がオブジェクトである場合、スプレッド演算子や Object.assign()
では浅いコピーしか行われません。つまり、内側のオブジェクトは参照渡しとなり、元のオブジェクトを変更すると、コピーされたオブジェクトも変更されてしまいます。
深いコピーが必要な場合は、JSON.parse(JSON.stringify())
を利用したり、専用のライブラリを使用したりする必要があります。
// 深いコピーの例 (JSON.parse(JSON.stringify()) を利用)
const person = {
name: '三郎',
address: {
city: '京都'
}
};
const deepCopyPerson = JSON.parse(JSON.stringify(person));
deepCopyPerson.address.city = '奈良';
console.log(person); // 出力: { name: '三郎', address: { city: '京都' } }
console.log(deepCopyPerson); // 出力: { name: '三郎', address: { city: '奈良' } }
- **Object.assign()**は、既存のオブジェクトにプロパティを追加する際に便利です。
- スプレッド演算子は、新しいオブジェクトを作成しながら結合する際に便利です。
どちらの方法を使うかは、結合したいオブジェクトの構造や、結合後のオブジェクトをどのように扱いたいかによって決まります。
- スプレッド演算子や
Object.assign()
は、オブジェクトのマージとも呼ばれます。 - プロパティとは、オブジェクトのキーに対応する値のことです。
- JavaScript のオブジェクトは、キーと値のペアの集合です。
for...in ループ
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const mergedObj = {};
for (const key in obj1) {
mergedObj[key] = obj1[key];
}
for (const key in obj2) {
mergedObj[key] = obj2[key];
}
console.log(mergedObj); // 出力: { a: 1, b: 2, c: 3, d: 4 }
- 手続き的な書き方になるので、スプレッド演算子や Object.assign() よりも冗長になることがあります。
- 同じキーが存在する場合、後のループで上書きされます。
- 各オブジェクトのキーを順に取得し、新しいオブジェクトにコピーします。
lodash の _.merge()
lodash は、JavaScript のユーティリティライブラリで、オブジェクトの操作を簡潔に行えるように様々な関数を提供しています。その中の _.merge() は、オブジェクトを深くマージする機能を持ちます。
const _ = require('lodash');
const obj1 = { a: 1, b: 2, c: { x: 1 } };
const obj2 = { c: { y: 2 } };
const mergedObj = _.merge({}, obj1, obj2);
console.log(mergedObj); // 出力: { a: 1, b: 2, c: { x: 1, y: 2 } }
- lodash を導入する必要があるため、プロジェクトの規模や依存関係によってはオーバーヘッドになる可能性があります。
- カスタムのマージロジックを実装することも可能です。
- ネストされたオブジェクトも深くマージすることができます。
ES6 の Map
Map は、キーと値のペアを格納するコレクションです。オブジェクトと似たような使い方もできますが、キーの型に制限がないという特徴があります。
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const map = new Map();
for (const [key, value] of Object.entries(obj1)) {
map.set(key, value);
}
for (const [key, value] of Object.entries(obj2)) {
map.set(key, value);
}
console.log(Object.fromEntries(map)); // 出力: { a: 1, b: 2, c: 3, d: 4 }
- キーの型に柔軟に対応できますが、少し冗長なコードになります。
- 最後に Object.fromEntries() で Map をオブジェクトに変換します。
- Map にオブジェクトのキーと値を順にセットします。
どの方法を選ぶべきか
- 手続き的な処理
for...in ループ - 柔軟なキーの扱い
Map - シンプルで浅いマージ
スプレッド演算子や Object.assign()
状況に応じて最適な方法を選択してください。
- JavaScript の新しいバージョンでは、オブジェクトの結合に関する機能がさらに強化される可能性があります。
- 上記以外にも、ライブラリによっては独自のオブジェクトマージ機能を提供している場合があります。
javascript javascript-objects