イミュータブル(immutable)について学習しました。勉強した内容を記録しています。間違ってたら修正します。
immutableは以下の要素に分解できます↓
- im:否定
- mut:変わる
- able:できる
上記より、「変えられない」と解釈でき、「不変な」という意味の単語です。
まず結論
JavaScriptにおいてイミュータブルとは、一度作成されたオブジェクトの状態(中身)が変わらないことを指します。具体的に述べると、オブジェクトのプロパティを操作しても、作成されたオブジェクトの中身が変わらない(影響を受けない)状態のことです。
以下にコード例を示します。↓
const string = "hello";
for(let i = 0; i < string.length; i++) {
//一文字ごとに大文字にする
string[i] = string[i].toUpperCase();
}
console.log(string); // hello
変数stringの各プロパティに対して1文字ずつ大文字にするような変更を加えても、出力結果は変わりません。
一般的にプリミティブは、プロパティやメソッドを持ちませんが、文字列や数値などのメソッドやプロパティにアクセスすると一時的にラッパーオブジェクトに変換して処理を実行します。
この処理を自動ボックス化と呼びます。
イミュータブル(immutable)な型
プリミティブ型はイミュータブルです。プリミティブとは、メソッドやプロパティを持たない型です。
以下の6種類があります↓
- String
- Number
- Boolean
- BigInt
- Undefined
- Symbol
- Null
UndefinedとNull以外のプリミティブ型にはそれぞれに対応するオブジェクトのような操作ができるラッパーオブジェクトが存在します。
例えば、普段文字列を生成するときは、const string = "文字列";
のように文字列リテラルを用いますが、以下のようにnew
演算子を用いても作成できます↓
const string = new String("文字列");
console.log(string); // String {'文字列'} {0:"文",1:"字",2:"列",length:3}
ラッパーオブジェクトについて詳しくはこちら↓
イミュータブル(immutable)ではない型
イミュータブルでないことをミュータブルと呼びます。意味は、オブジェクトのプロパティを操作すると、作成したオブジェクトの状態(中身)が変わることを指します。
イミュータブルではない型の例です↓
- Object
- Array
- Date
基本的にプリミティブ型以外がミュータブルです。
以下は配列がミュータブルであることを表すコードです↓
const array = [1,2,3,4,5];
for (let i = 0; i < array.length; i++) {
array[i] = array[i] * 2;
}
console.log(array); // [2,4,6,8,10]
上記のコードでは、配列の中身の一つ一つに対して変更を加えています。結果を見ると変数arrayの中身が最初に作成された状態から変わっています。
ミュータブルな型をイミュータブルにする
配列やオブジェクトはデフォルトでミュータブルです。
イミュータブルな操作をする例として、スプレッド構文を用いてオブジェクトのコピーを作成して、そのオブジェクトのプロパティ操作する方法があります↓
const array= [1,2,3,4,5];
const newArray = [...array];
for(let i=0;i<newArray.length;i++){
newArray[i]=newArray[i]*2;
}
console.log(array); // [1,2,3,4,5]
console.log(newArray); // [2,4,6,8,10]
上記のコードでは元の配列arrayに影響を与えていないことがわかります。
ただ、オブジェクトの中身が階層化されている場合、イミュータブルな操作はできません↓
const array= [1,2,3,4,[5,6]];
const newArray = [...array];
newArray[3] = 50;
newArray[4][0]=10;
console.log(array); // [1,2,3,4,[10,6]]
console.log(newArray); // [1,2,3,50,[10,6]]
配列arrayと配列newArrayの4番目の値が、同じになっています。このように階層化されたオブジェクトをイミュータブルに操作するにはstructuredClone
メソッドを使用します↓
const array= [1,2,3,4,[5,6]];
const newArray = structuredClone(array);
newArray[3] = 50;
newArray[4][0]=10;
console.log(array); // [1,2,3,4,[5,6]]
console.log(newArray); // [1,2,3,50,[10,6]]
structuredCloneについてはこちら↓
まとめ
イミュータブルとは、オブジェクトのプロパティを操作しても、作成したオブジェクトの状態(中身)が変わらないことです。
今回の学習を通してイミュータブルについて0.1%ぐらい理解できたのではないかと思い込むことができました。
間違ったことを書いていた場合、気付いた時点で修正していきます。