【TypeScript】Objectのディープコピー
こんばんは葛の葉です。
Javascriptのディープコピーをちょっと書きます。Javascriptではconst copyedObj = JSON.parse(JSON.stringify(obj));
を使うと思います。
const obj1 = { hoge: 1, piyo: "hiyoko", fuga: true }; const copyedObj1 = JSON.parse(JSON.stringify(obj1)); obj1.hoge = 2; console.log(copyedObj1.hoge === 1); // true console.log(copyedObj1); // { hoge: 1, piyo: 'hiyoko', fuga: true }
しかし、以下のStackOverflowには
Fast cloning with data loss - JSON.parse/stringify If you do not use Dates, functions, undefined, Infinity, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays or other complex types within your object, a very simple one liner to deep clone an object is: JSON.parse(JSON.stringify(object))
Date型や関数, undefined, Infinityや正規表現、その他もろもろのものについてはコピーできないということです。
const obj2 = { moge: undefined, date: new Date("2020/01/01Z"), func: function () { return 'hogehoge'; }, reg: /^https/g }; const copyedObj2 = JSON.parse(JSON.stringify(obj2)); console.log(copyedObj2); // { date: '2020-01-01T00:00:00.000Z', reg: {} };
Date型はJSONになるタイミングでISO 8601形式のstring型になります。正規表現オブジェクトについては、空のオブジェクトに変更されます。こういった一部の型についてはコピーすることが出来ないようです。おそらくJsonが文字列しかないからなのかなぁって思います。
じゃあどうやってディープコピーするの?
先のStackOverflowにも書いてあったんですけど、頑張ってコード書いてもいいけど基本的にライブラリやフレームワークのメソッドを使おうってことみたいです。私が使ったのはこちらのライブラリ。
Typescriptの型はこちら
import clone from "clone"; const obj2 = { moge: undefined, date: new Date("2020/01/01Z"), func: function () { return 'hogehoge'; }, reg: /^https/g }; const copyedObj2 = clone(obj2); console.log(copyedObj2); /* { moge: undefined, date: 2020-01-01T00:00:00.000Z, func: [Function: func], reg: /^https/g } */ console.log(copyedObj2.func()); // hogehoge