コピーしたつもりでコピー元の値を変更するとコピー先も変わっていたなんてことよくありませんか?
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'}}