2020.4.23

配列やオブジェクトのディープコピー(JSON.parse、JSON.stringify)

配列やオブジェクトを簡単にディープコピーする方法として、「JSON.parse」と「JSON.stringify」を使ったものがありますが、元の内容によってはコピーされずに情報が欠けてしまうことがあるので、使用時には注意が必要です。

目次

  • コード
  • 配列
  • オブジェクト
  • オブジェクト(メソッド付き)

コード

JSON.parse() はJSON形式の文字列をJSONオブジェクト(配列、オブジェクト)に変換してくれるメソッド。JSON.stringify() は配列やオブジェクトをJSON形式の文字列に変換してくれるメソッド。

JSON.parse() と JSON.stringify() を使ったディープコピーのコードは以下のようになります。


var copyObj = JSON.parse(JSON.stringify(obj));

以下、配列やオブジェクトのコピーの使用例、また、コピーできないものもあるので、その注意点です。

配列

配列のディープコピー。


var arr = [
  { id: 1, name: "a", data: ["a1", "a2", "a3"] },
  { id: 2, name: "b", data: ["b1", "b2", "b3"] }
];

console.log("元データ", arr);
console.log("コピー後", JSON.parse(JSON.stringify(arr)));

実行結果は以下の通りとなります。

元データ
  0:
    data: (3) ["a1", "a2", "a3"]
    id: 1
    name: "a"
  1:
    data: (3) ["b1", "b2", "b3"]
    id: 2
    name: "b"

コピー後
  0:
    data: (3) ["a1", "a2", "a3"]
    id: 1
    name: "a"
  1:
    data: (3) ["b1", "b2", "b3"]
    id: 2
    name: "b"

上記の場合、元データとコピー後のデータは同じになります。

オブジェクト

オブジェクトのディープコピー。


var obj = {
  id: 11,
  name: "hoge",
  data: [
    { id: 111, name: "hoge1" },
    { id: 112, name: "hoge2" },
    { id: 113, name: "hoge3" }
  ],
};

console.log("元データ", obj);
console.log("コピー後", JSON.parse(JSON.stringify(obj)));

実行結果は以下の通りとなります。

元データ
  data: Array(3)
    0: {id: 111, name: "hoge1"}
    1: {id: 112, name: "hoge2"}
    2: {id: 113, name: "hoge3"}
  id: 11
  name: "hoge"

コピー後
  data: Array(3)
    0: {id: 111, name: "hoge1"}
    1: {id: 112, name: "hoge2"}
    2: {id: 113, name: "hoge3"}
  id: 11
  name: "hoge"

上記の場合、配列同様に元データとコピー後のデータは同じになります。

オブジェクト(メソッド付き)

オブジェクト(メソッド付き)のディープコピー。


var obj2 = {
  id: 34,
  name: "fuga",
  data: [
    { id: 341, name: "fuga1" },
    { id: 342, name: "fuga2" },
    { id: 343, name: "fuga3" }
  ],
  test: function(id){
    return id > 0;
  }
};

console.log("元データ", obj2);
console.log("コピー後", JSON.parse(JSON.stringify(obj2)));

実行結果は以下の通りとなります。

元データ
  data: Array(3)
    0: {id: 341, name: "fuga1"}
    1: {id: 342, name: "fuga2"}
    2: {id: 343, name: "fuga3"}
  id: 34
  name: "fuga"
  test: ƒ (id)

コピー後
  data: Array(3)
    0: {id: 341, name: "fuga1"}
    1: {id: 342, name: "fuga2"}
    2: {id: 343, name: "fuga3"}
  id: 34
  name: "fuga"

上記の場合、メソッドがコピーされていないのが分かります。

簡単にディープコピーできる JSON.parse(JSON.stringify(obj)) ですが、単純なデータしかコピーされないので、配列やオブジェクトをディープコピーをする際は、上記の点に注意する必要があります。

JavaScript】関連記事