勘違いしやすいオブジェクトの参照とコピー

@ハクト 2022-09-26 13:59:59に投稿

コピーしたつもりでコピー元の値を変更するとコピー先も変わっていたなんてことよくありませんか?

JavaScriptで配列やオブジェクトを代入すると参照渡しとなり、元のデータを変更すると代入先の値も変わってしまいます。

今回は配列やオブジェクトを値渡したい場合のコピー方法について解説します。コピーにも浅いコピー、深いコピーと二種類あり挙動が違うので、オブジェクトデータによって使い分けていきましょう。

オブジェクトの参照と二種類のコピー方法

参照

let user1={
  id:1, name:'yamada'
}
let user2 = user1;
user1.name='suzuki'; //参照の為、「user2」の「name」も変わる   

console.log(user1); //{id: 1, name: 'suzuki'}
console.log(user2); // {id: 1, name: 'suzuki'} 

 

浅いコピー(Object.assign

let user1={
  id:1, name:'yamada',
  history:{ data1:'aaa',data2:'bbb' }
}
let user2 = Object.assign({}, user1);
user1.name='suzuki'; //コピーなので「user1」の「name」だけ変わる
user1.history.data1='ccc'; //浅いコピーなので「user2」の「data1」が参照になり、変更されてしまう

console.log(user1);  //{id: 1, name: 'suzuki', history:{data1:'ccc',data2:'bbb'}}
console.log(user2);  //{id: 1, name: 'yamada', history:{data1:'ccc',data2:'bbb'}}

 

深いコピー(JSON.parse JSON.stringify()

let user1={
  id:1, name:'yamada',
  history:{ data1:'aaa',data2:'bbb' }
}
//「JSON.stringify」でJSON文字列に変換→「JSON.parse」で文字列をオブジェクトに変換
let user2 = JSON.parse(JSON.stringify(user1));
user1.name='suzuki';
user1.history.data1='ccc';

console.log(user1);  //{id: 1, name: 'suzuki', history:{data1:'ccc',data2:'bbb'}}
console.log(user2);  //{id: 1, name: 'yamada', history:{data1:'aaa',data2:'bbb'}}

 

 

@ハクト

サービス作り・デザイン好き。70年代生まれのWEBエンジニア。WEBパーツをCSSでカスタマイズしてコピペできるサービスを運営中「Pa-tu」。実装したWEBパーツやツールを利用してWEB情報やライフハックを発信してます。

Twitter