2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JavaScript(ES6/ES2015)でオブジェクトをコピーする時に注意すること

Last updated at Posted at 2018-07-10

どうも、はぐっです・ω・♪

JavaScript(ES6/ES2015)でオブジェクトをコピー」

もう、babelを利用してES6/ES2015でJavaScriptを書いている人もだいぶ増えて来たことかと思います。で、様々な場面でオブジェクトを扱うことが多くあるはずっ。
んで、コピーしたいなんてこともあるはずっ。
そんなとき、コピーの仕方はいくつかあると思いますが、ここでは二つのやり方を。

コピーの方法

jQueryを利用してオブジェクトをコピー

JavaScript界の大ベテラン、「jQuery」
こいつに、オブジェクトをコピーする時に使えるメソッドが用意されています。
(本来の目的はオブジェクトのマージだったり。)

$.extend

使い方は

let firstObj = {
  a: 'a',
  b: {
    a: 'a',
    b: {
      a: 'a'
    }
  }
};

let secondObj = $.extend(true, {}, firstObj);

はいっ、こぴー。

引数はこちら。

第一引数       : ディープコピーかどうか(省略可)
第二引数       : マージのもととなるオブジェクト
第三引数以降 : マージするオブジェクト(いくつでも)

ん?
ディープコピー?

そう!
今回はここがポイントです!

ディープコピーとは

まぁ、「とは」っていうほど定義が必要なものではなくて、

deep:深い

つまり、深いコピーをするか、浅いコピーをするか。
下の階層まで再帰的にコピーするか。

ここ、割と大事。

ES6/ES2015を利用してオブジェクトをコピー

ES6/ES2015になって、
待ってましたー!!!!
な機能が様々追加され、いろいろとはっぴーになったわけですが、

その中の一つ。

Object.assign

こいつ。

使い方は

let firstObj = {
  a: 'a',
  b: {
    a: 'a',
    b: {
      a: 'a'
    }
  }
};

let secondObj = Object.assign({}, firstObj);

はいっ、こぴー。

第一引数       : マージのもととなるオブジェクト
第二引数以降 : マージするオブジェクト(いくつでも)

うむ。
さっきのjQueryのextendと使い方自体はそうかわら・・・

ディープは!?

そう、ここが違うのです。

Object.assignは、シャローコピー(ディープコピーと違って浅いコピー)なのです!!

これね、困る時があるんですよ。

コピーの方法による違い

例えば

let firstObj = {
  a: 'a',
  b: {
    a: 'a',
    b: {
      a: 'a'
    }
  }
};

があったとしてですよ。

$.extendの場合

let secondObj = $.extend(true, {}, firstObj);

secondObj.b.a = 2;

console.log(firstObj.b.a); // 1
console.log(secondObj.b.a); // 2

この場合、出力は

1: a
2: 2

となります。

Object.assignの場合

let secondObj = Object.assign({}, firstObj);

secondObj.b.a = 2;

console.log(firstObj.b.a); // 1
console.log(secondObj.b.a); // 2

この場合、出力は

1: 2
2: 2

となります。

ほらああああああああああ!!!

こういうところで違いがでてくるんですよ!

だから言ったじゃないですかあああ!

…こほん。

つまりね、

オブジェクトがプロパティとしてオブジェクトを持っている時、

シャローコピー(Object.assign)だと同じ参照
ディープコピー($.extend(true))だと別参照

となるわけですね。

みなさま、くれぐれもオブジェクトのコピーは慎重に。

ES6/ES2015のご利用は計画的に。

2
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?