UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【JavaScript】ディープクローンにはstructuredCloneを使う

こちらのブログを読んで、オブジェクトのディープクローンにはstructuredCloneを使うと良いことを知った

www.builder.io

JavaScriptはコピーしたオブジェクトとコピー元のオブジェクトでプロパティにおいて同じ参照を共有するコピー(シャローコピー)と参照を共有しない(ディープコピー)がある

コピー元かコピー先のどちらかを変更しても、そのほかのオブジェクトにも変更を及ぼしていないことを保証したい場合はディープクローンを使う

今までディープクローンを作成する場合は JSON.stringify() でオブジェクトを JSON 文字列に変換し、さらに JSON.parse() で文字列からJavaScript のオブジェクトに変換していた

const deepcopy = JSON.parse(JSON.stringify(ingredients_list));

ただこれでは、いくつか問題がある

例えば、Date型のプロパティが文字列のままになってしまう

{
  date: "1970-01-01T00:00:00.123Z"
}

その他にも記事を引用させてもらうと以下の結果は

const kitchenSink = {
  set: new Set([1, 3, 3]),
  map: new Map([[1, 2]]),
  regex: /foo/,
  deep: { array: [ new File(someBlobData, 'file.txt') ] },
  error: new Error('Hello!')
}

const veryProblematicCopy = JSON.parse(JSON.stringify(kitchenSink))

このようになってしまう

{
  "set": {},
  "map": {},
  "regex": {},
  "deep": {
    "array": [
      {}
    ]
  },
  "error": {},
}

structuredCloneはこれを解決する developer.mozilla.org