見出し画像

TypeScript 入門の記録(36)プロを目指す人のためのTypeScript入門(21)オブジェクトはいつ❝同じ❞なのか

前回に続き、オブジェクトについて学習します。今回は、オブジェクトの等値性について、理解したいと思います。

オブジェクトはいつ❝同じ❞なのか

他のプログラミング言語でもオブジェクトの比較は注意が必要なことが多いのですが、TypeScript の場合はどうなのか?を確認します。

変数とオブジェクトの関係

JavaやC#でも、変数にオブジェクトを代入すると、オブジェクトの実体は自動コピーされず、同じオブジェクトの場所を指します。オブジェクトを複製する場合は、明示的な内容のコピーが必要です。これと同様に、TypeScriptでも、オブジェクトの場所を変数に代入するところは同じなので、理解しやすいです。

変数barにfooを代入すると、barのプロパティ変更がfooにも反映される
変数fooと変数barは、同じオブジェクトを指す

オブジェクトのコピー方法

Java の DeepCopy みたいにオブジェクトの実体を複製するには、前回学習した、スプレッドが利用できるようです。変数に代入するのではなく、それぞれのオブジェクト変数を定義すれば確実です。別々に使いたいなら、別々に定義するのが安全というのは、その通りだなぁと思います。(誤ってプロパティを書き換えてしまったりすることが避けられます)

fooを元にbarをスプレッド構文で定義したあとでbar.numを変更してもfooには影響しない

オブジェクト変数とプリミティブ型の変数との違いが意識できていればOKですね。

スプレッド構文を利用して複製したオブジェクトの変更は元のオブジェクトに影響しない

スプレッド構文は便利ですが、プロパティにネストしたオブジェクトが含まれている場合は、そのネストしたオブジェクトは複製されないため、プロパティのオブジェクトは、変わらず、元のオブジェクトを指している状態です。便利だけれど、オブジェクトのプロパティが更にオブジェクトである場合の罠ですね。そんな危険を避けるためには、それぞれの変数をスプレッド構文を使わずに、それぞれ別々に定義しておく方が安全ということですね。これは、うっかりやらかしてしまいそうなので、気をつけたいと思いました。

fooは、bar.obj.numの変更の影響を受ける

オブジェクトの比較

オブジェクト同士の比較をしてみると、オブジェクト変数同士を比較する場合は、その参照先が同じであれば同じと判定されます。(参照先のアドレスを比較しているイメージ)プロパティの値が同じであっても、別定義のオブジェクトは同じとはみなされません。これも、オブジェクト変数は、そのオブジェクトの場所が保存されていると考えると理解しやすいと思いました。

中身が一致しているか?ではなく、参照先が一致しているかを比較する

中身が一致しているかどうか?は、標準的な比較方法は無いそうです。これは、各プロパティを比較して、一致するかどうかを判定する必要がありますね。ちょっと手間すぎるので、比較用の関数を作っても良さそうです。

さて、今日の学習はここまでにします。
次回は「オブジェクトの型」について学習する予定です。

いいなと思ったら応援しよう!