LoginSignup
1
1

More than 3 years have passed since last update.

Object.assign()で深い部分もコピーしたい!

Posted at

やりたいこと

Const  State = {
    name: Hanako,
    stay: {
        Japan: {
              Hiroshima: 実家,
              Karuizawa: 別荘,
               },
        America: {
              NewYork: 別荘,
              Arizona: おじいちゃんち
                 }
          }
};

これのKaruizawaを'実家2'にしたコピーが欲しい!
StateのstayのJapanのKaruizawaが書き換わるのはいやだ

Object.assign()は浅いコピーのため、一回のコピーでご丁寧に入れ子の中までコピーはしてくれません。

今の状態で、State2を定義して、Stateをコピーした後、Karuizawaの中身をみると、

Const State2 = Object.assign({}, State);
Console.log(State.stay.Japan.Karuizawa);
-> 別荘

試しに、State2.stay.Japan.Karuizawa に'実家2'を代入してみます。

失敗例1
State2.stay.Japan.Karuizawa = 実家2;
Console.log(State.stay.Japan.Karuizawa);
-> 実家2

これだと、最初のStateの中のKaruizawaが'別荘'ではなく、'実家2'に書き変わってしまっています。
そうじゃない。Karuizawaが'別荘'のバージョンと'実家2'のバージョンの二つが欲しい、書き変わってほしくないので、このコピーは失敗です。

失敗例2
State2= Object.assign({}, State);
State2.stay.Japan= Object.assign({}, State.stay.Japan, { Karuizawa: 実家2} )
Console.log(State.stay.Japan.Karuizawa);
-> 実家2

↑このパターンも書き変わってしまいます。失敗・・・

では、成功例はというと、

成功例
State2= Object.assign({}, State);
State2.stay = Object.assign({}, State.stay);
State2.stay.Japan = Object.assign({}, State.stay.Japan);
State2.stay.Japan = Object.assign({}, State.stay.Japan, { Karuizawa: '実家2'});

一旦ここまで丁寧にコピーしてやります。
それぞれの中身をみてみましょう。

console.log(State2);
=>{ name: 'Hanako',
  stay:
   { Japan: { Hiroshima: '実家', Karuizawa: '実家2' },
     America: { NewYork: '別荘', Arizona: 'おじいちゃんち' } } }

console.log(State2.stay.Japan.Karuizawa);
=>実家2

console.log(state.stay.Japan.Karuizawa);
=>別荘

Stateの方のKaruizawaは '別荘' のままです。書き変わってません!成功です!!

シャローコピーで粘りたい方は、この方法おすすめです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1