見出し画像

【危機感】ミュータブルとイミュータブルについて曖昧だと危ない!!![JavaScript][PHP]

日常会話でミュータブル、イミュータブルって使わないですよね。実はイミュータブルには恐ろしい罠が潜んでいるのです。。。実例と共に深掘りしていきましょー

この機会に公式ドキュメントから読み解いて理解を深めるゾイ

ミュータブル、イミュータブルってなんぞ?

まずは公式のMDNから引用します。

ミュータブルは、変更可能な変数の型です。JavaScript では、プリミティブな値ではない、オブジェクト配列だけがミュータブルです。

(変数名が新しい値を指し示すようにすることはできますが、以前の値はまだメモリーに保持されていますので、ガベージコレクションが必要です。)

ミュータブルオブジェクトは、オブジェクトを作成した後に状態を変更できるオブジェクトです。

イミュータブルは、オブジェクトが作成された後は状態を変更できないオブジェクトです。

文字列数値イミュータブルです。例をあげて理解しておきましょう。

以下に記載[1]

では読み解いて行きましょう!
先頭から

ミュータブルは、変更可能な変数の型です。JavaScript では、プリミティブな値ではない、オブジェクトと配列だけがミュータブルです。

[1]より抜粋

PHPの書き方については後ほど登場します!
まずはJavaScriptで理解を深めて行きましょう!

JavaScriptのプリミティブ === イミュータブルです。
以下のコードの変数たちがまさにイミュータブル

JavaScriptだとミュータブルな値は具体的には以下の感じ

ミュータブルオブジェクトは、オブジェクトを作成した後に状態を変更できるオブジェクトです。

上記[1]

この上記の文がやっかいで理解してないと意図しないバグ混入の恐れがあります😰

以下のコードではmyObjのnameプロパティを変更して新しくnewMyObjというオブジェクトを作成しています。

求める仕様

  • 太郎の名前を含んだオブジェクトと二郎の名前を含んだオブジェクトを出力する

出力結果は以下のようになります。

myObj: {name: "二郎", score:100}
newMyObj: {name:"二郎", score:100} 

変更を加えたいのがnewMyObjだけなのにmyObjの値まで変更されてしまいます(@_@)

なんでオブジェクトや配列を扱うときは

上記一行みたいに気軽にオブジェクトに直接渡すのはバグの元になります💦

対策

JavaScriptでは3行目のスプレッド演算子(3点ドットのこと)を用いた書き方をすることで簡単に別のオブジェクトとして扱うことができます。(これは配列でも同様です)またこのようなコピーのことをディープコピーと言います。

PHPだとどう書くの?

まずは、ミュータブルの危険性を意識していない以下のコードから確認しましょう

上記コードでは、トランプカードゲームの戦争を管理するGameManagerクラスの中のplayメソッドです。

playメソッドについて

playメソッドではゲームを開始してゲーム終了するまでの処理を担います。
6行目の

のようなコードを放置していると、candidateWinnerPlayersだけで変更したかった条件がいつのまにかplayersにも影響を与えてしまい、意図しない挙動を生む可能性があります💦

対策

上記のようにclone関数を用いることで$playerインスタンスをディープコピーします。これにより$candidateWinnerPlayersが変更されても$playersに影響しないので安全にインスタンスがちゃがちゃできるようになりますd(^_^o)

ミュータブル、イミュータブルを極めて安全な開発ライフを送りましょう!!!

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