【JavaScript】Object.assignでオブジェクトのコピーを作る
はじめに
参照型のデータを扱う際に、Object.assignメソッドを使ってオブジェクトのコピーを作る方法を学んだのでその記録です。
Object.assignとは
MDNの定義は以下。
Object.assign() メソッドは、すべての列挙可能なプロパティの値を、1つ以上のコピー元オブジェクトからコピー先オブジェクトにコピーするために使用されます。戻り値としてコピー先オブジェクトを返します。
使用例はこちら。
let a = { x: 1, y: 2, z: 3 }; let b = { x: 5, y: 6, }; let c = { x: 7 }; //戻り値としてコピー先のオブジェクト(a)を返す Object.assign(a, b, c); //=> { x: 7, y: 6, z: 3 } //コピー先のオブジェクト(a)は変更される //コピー元のオブジェクト(bとc)は変更されない console.log(a); //=> { x: 7, y: 6, z: 3 }; console.log(b); //=> { x: 5, y: 6, }; console.log(c); //=> { x: 7 };
Object.assignは第一引数の値(a)がコピー先になり、その後に続く値(b,c)がコピー元になる。
コピー先の値とコピー元の値がマージされる。
マージする際に、コピー先とコピー元に同じプロパティが存在する場合は、コピー元の値が優先され、コピー先の値は上書きされる。
コピー元の値が複数ある場合(上記例のbとc)は後のものが優先される(bよりcが優先される)
上記の例では、変数aのyの値は変数bのyで上書きされ6になる。変数aのxの値は変数bのxの値で上書きされ、さらに変数cのxの値で上書きされるため、結果的に7になる。
Object.assingでコピーを作る
例えば以下のような場合。
let a = { x: 1, y: 2, z: 3 }; let b = a; console.log(b); //=> { x: 1, y: 2, z: 3 }; a["x"] = 10; console.log(a); //=> { x: 10, y: 2, z: 3 }; console.log(b); //=> { x: 10, y: 2, z: 3 };
JavaScriptでは配列やオブジェクトは参照型のため、aの値が変更されるとbの値も変更されてしまう。
そこで、aのコピーを作り、それを利用すればbに影響を与えずに済む。 コピーを作るには以下のようにする。
let a = { x: 1, y: 2, z: 3 }; let b = a; // aのコピーを作り、変数cに代入する let c = Object.assign( {}, a ); // 変数cにはaの値がコピーされている console.log(c) //=> { x: 1, y: 2, z: 3 }; // 変数cの値を変更する c["x"] = 10; console.log(a) //=> { x: 1, y: 2, z: 3 }; console.log(b) //=> { x: 1, y: 2, z: 3 }; console.log(c) //=> { x: 10, y: 2, z: 3 };
Object.assignの第一引数(コピー先)に空のオブジェクトを用意し、コピー元の要素を第二引数以降に指定する。
aとcは別のオブジェクトになるため、cの値をいくら変更してもコピー元のaには影響せず、また、aを参照するbにも当然ながら影響を与えない。
まとめ
参照型の挙動を意識していないと、思わぬところに影響を与える可能性があるので注意しましょう。