TypeScriptでオブジェクトをコピーする方法をわかりやすく解説

2023.08.05 に更新記事は 4 分で読めます
サムネイル画像

TypeScriptやJavaScriptのコードを書く際、オブジェクトのコピーをしたことはありますか?
その際、本当に思った通りの動作をしてくれましたか?

この記事ではオブジェクトの参照渡し、シャローコピー、ディープコピーについて紹介していきます!

この記事を読むことで得られること

TypeScriptを使ったプログラミングで避けては通れない「オブジェクトのコピー」について紹介します。

「参照渡し」「シャローコピー」「ディープコピー」とは何か
それぞれの違いと使いどころを具体的なコード例とともに解説します。
これらの知識を身につけることで、オブジェクトの扱いに悩むことが少なくなるでしょう!

オブジェクトのコピーは独特:参照渡し

まずは、オブジェクトの基本的な性質から学びましょう。

let obj1 = {name: "Hoge", age: 20};
let obj2 = obj1;
obj2.name = "Fuga";

console.log(obj1.name);

コード内では obj1.name を出力していますが Fuga が表示されてしまいます。

obj2 を変更しただけなのに、なぜ obj1 の内容まで変わるのでしょう?
これは obj2 = obj1; の部分で obj1 の参照を obj2 にコピーしているからです。
そのため obj2 で行われた変更は obj1 にも反映されるのです。

これが 参照渡し と呼ばれるものです。

オブジェクトのコピーを安全に:シャローコピー

先程の参照渡しの挙動を避ける方法の一つが シャローコピー です。

let obj1 = {name: "Hoge", age: 20};
let obj2 = {...obj1};
obj2.name = "Fuga";

console.log(obj1.name);

上記のコードでは Hoge が表示されるはずです。
これがシャローコピーの力です。

ここでは {...obj1} を使って obj1 のプロパティを新しいオブジェクトにコピーしています。
そのため obj2 への変更が obj1 に影響を与えません。

ただし、この方法も万能ではありません。
オブジェクトがネストされている場合(オブジェクトの中にオブジェクトがある場合)には、この方法だけでは完全なコピーを作成することができないため注意が必要です。

全てをコピーする:ディープコピー

ネストされたオブジェクトに対しても対応可能なコピー方法が、ディープコピーです。

let obj1 = {name: "Hoge", age: 20, address: {country: "Japan", city: "Tokyo"}};
let obj2 = JSON.parse(JSON.stringify(obj1));
obj2.address.city = "Nagoya";

console.log(obj1.address.city);

上記のコードを実行すると Tokyo が表示されます。
この方法によってネストされたオブジェクトに対しても完全なコピーが可能となります。

ここでは JSON.parse(JSON.stringify(obj1)) を利用して obj1 を一度 JSON 文字列に変換し、再びオブジェクトに戻すことでオブジェクト全体を新しいオブジェクトにコピーしています。

他にも Lodash を使用してディープコピーを行う方法などが存在します。

以上がTypeScriptでのオブジェクトのコピーに関する基本的な知識です。
覚えておくと便利なのでぜひご活用ください!

プロフィールアイコン

Syuu

フロントエンドが好きなWEBエンジニア Next.js / React / TypeScript

SHARE