【JavaScript入門】ObjectをCopy・Mergeする方法 | Object.assign()・スプレッド構文

Object-Copy-Merge

こんにちは、フロントエンドエンジニアのまさにょんです。

今回は、JavaScriptで、ObjectをCopy・Mergeする方法について解説して行きます。

前回・前々回と、配列のCopy・Mergeについて解説しました。

そちらが気になる方は、Checkしてみてください。

配列をCopyする方法
配列をMergeする方法

Object.assign() でObjectをCopyする方法

ObjectをCopyする方法として、Object.assign() と「スプレッド構文」(Spread-Syntax)の2つがあります。

それぞれ解説して行きます。

「 Object.assign() 」は、Object専用のメソッドで第一引数にCopy先のObjectを指定して、第二引数・以降にCopyするObjectを指定することで、Objectを合成(Merge)するメソッドです。

なので、第一引数に「 {} 」(空Object)を指定すると値渡し-Copyができますし、既存のObjectを指定すれば既存のObjectに他のObjectをMergeできます。

Object.assign()
構文: Object.assign(target, ...sources);

引数:  target, sources
 1. target: コピー先オブジェクト — コピー元のプロパティを適用するもので、変更後に返されます。
 2. sources: コピー元オブジェクト (単数または複数) — 適用したいプロパティを含むオブジェクトです。

実行結果(返値): コピー先オブジェクトです。
// < Object.assign()を使用したCopy >

const obj = { a: 1, b: 2 };

// 1. 「値渡し-Copy」(Pass by value)
const copyObj = Object.assign({}, obj);

// 2. copyObjを更新する
copyObj.a = 12;

console.log({obj});
// obj: {a: 1, b: 2}

console.log({copyObj});
// copyObj: {a: 12, b: 2}

スプレッド構文(Spread-Syntax)でObjectをCopyする

「スプレッド構文」(Spread-Syntax)は、ArrayやObjectを展開するのに使える構文です。

「 … 」の後にArrayやObjectを記述することで、その中身を展開します。

スプレッド構文は、元のArrayやObjectには変更を加えない非破壊的な記法なので、Copyに使えます。

// < spread構文を使用したCopy >
const robotama = {id:1,pirotName:'群馬のまー', name: 'ロボ玉'};

// 1. spread構文で一度展開してから再度、{}で包むとCopyできる。
const copyRobotama = {...robotama};

// 2. CopyしたObjectに新しいkey&valueを追加する。
copyRobotama.from = 'グンマー帝国';

console.log({robotama});
// robotama: {id: 1, pirotName: '群馬のまー', name: 'ロボ玉'}

// 3. Copyだけ変更 => Spread構文のCopyは「値渡し」(Pass by value)で、非破壊的!
console.log({copyRobotama});
// copyRobotama: {id: 1, pirotName: '群馬のまー', name: 'ロボ玉', from: 'グンマー帝国'}

Object.assign() でObjectをMergeする方法

ObjectのMerge方法もCopyと同様、Object.assign() または、「スプレッド構文」(Spread-Syntax)を使って行います。

まずは、Object.assign()を使って既存のObjectを加工する方法を見て行きましょう。

// < Object.assign()を使用したMerge Ver.既存のObjectを加工する >

const momo = {id:1,pirotName:'ももちゃん', from: '千葉'};

const hakutou = {id:2,pirotName: '白桃',name:'ロボ玉試作3号機', special: '白桃ビーム'};

const momoAndHakutou = Object.assign(momo, hakutou);

// 1. 第一引数に指定したObjectは、直接加工される!
console.log({momo});
// momo: {id: 2, pirotName: '白桃', from: '千葉', name: 'ロボ玉試作3号機', special: '白桃ビーム'}

console.log({hakutou});
// hakutou: {id: 2, pirotName: '白桃', name: 'ロボ玉試作3号機', special: '白桃ビーム'}

// 2. Object.assign()を使用したMerge-Result
console.log({momoAndHakutou}) 
// momoAndHakutou: {id: 2, pirotName: '白桃', from: '千葉', name: 'ロボ玉試作3号機', special: '白桃ビーム'}

Object.assign()を使って、元のObjectを破壊せずMerge(合成)する場合は、第一引数を「空Object」にしてMergeします。

// < Object.assign()を使用したMerge Ver.元のObjectを破壊しない >

const tokyo = {id:1, pirotName:'東京のまー', favoriteMovie: '翔んで埼玉', from: 'グンマー帝国'};

const gunma = {id:2, pirotName: 'ロボ玉', name:'ロボ玉試作2号機'};

// 1. 第一引数がAssign(割り当て)のtargetなので、{}(空のObject)を渡すと、そこに第二引数以降のObjectをAssignしてくれる。
const mergeJapanCapital = Object.assign({}, tokyo, gunma);

console.log({tokyo});
// tokyo: {id: 1, pirotName: '東京のまー', favoriteMovie: '翔んで埼玉', from: 'グンマー帝国'}

console.log({gunma});
// gunma: {id: 2, pirotName: 'ロボ玉', name: 'ロボ玉試作2号機'}

// 2. 元のObjectたちは、破壊されず新しいMerge-Objectの完成!
console.log({mergeJapanCapital});
// mergeJapanCapital: {id: 2, pirotName: 'ロボ玉', favoriteMovie: '翔んで埼玉', from: 'グンマー帝国', name: 'ロボ玉試作2号機'}

// 3. Spread-構文の方がシンプルに記述できるので、おすすめ!
const spreadMerge = { ...tokyo, ...gunma };

console.log({spreadMerge});
// spreadMerge: {id: 2, pirotName: 'ロボ玉', favoriteMovie: '翔んで埼玉', from: 'グンマー帝国', name: 'ロボ玉試作2号機'}

スプレッド構文(Spread-Syntax)でObjectをMergeする

スプレッド構文(Spread-Syntax)でObjectをMergeする際の注意点は、既にあるkeyに関しては後からMergeする方のvalueでupdateされるという点です。

次のSample-Codeを見ていただければ分かる通り、後からMergeする方のvalueでupdateされていますね。

// < spread構文を使用したMerge >

const object1 = {id:1,pirotName:'群馬のまー'};

const ID = 12;

// 1. id に ID を紐付けてMerge => id は既にある値なので、後から入って来た値でupdateされる!
console.log({ ...object1, id:ID});
// {id: 12, pirotName: "群馬のまー"}

const roboBall = {id:1,pirotName:'群馬のまー', name: 'ロボ・ボール'};

const prototypeRobo = {id:2,pirotName:'東京のまー', name:'ロボ玉試作1号機', special: 'ロボ玉ビーム'};

// 2. ObjectとObjectのMerge
const mergedRobo = { ...roboBall, ...prototypeRobo };

// 3. 重複しているkeyのvalueは、後から合成(Merge)する方でupdateされる!
console.log(mergedRobo);
// {id: 2, pirotName: '東京のまー', name: 'ロボ玉試作1号機', special: 'ロボ玉ビーム'}

以上、Object.assign()とSpread-Syntaxを使用したObjectのCopyとMerge方法でした。

JavaScript書籍 Ver. 中級-上級者向け

JavaScript書籍 Ver. 初級者向け

参考・引用

  1. MDN: Object.assign()
  2. MDN: スプレッド構文

最近の投稿