プリミティブ型とオブジェクト型
プリミティブ型には、number, string, boolean, symbolなどがあります。これらは不変の値で、直接操作することはできません。
プリミティブ型の値が不変であるというのは一度作成された値は変更できないという意味。
let str = "hello";
str[0] = "H";
console.log(str); // "hello"
このようにプリミティブ型の値は変更しようとしても変更できない。
let str = "hello";
str = "Hello";
console.log(str); // "Hello"
このように新しい文字列をメモリ上に確保してそのメモリーに対するポインターを再代入するという形で変数を書き換えることは可能。
ここで重要なのは元の文字列自体が変更されていないということ。
一方、Number, String, Boolean, Symbol, ObjectはJavaScriptのオブジェクト型です。これらはプリミティブ型の値をラップするオブジェクトで、メソッドやプロパティを持つことができます。例えば、Stringオブジェクトはプリミティブ型のstringをラップし、文字列操作のためのメソッドを提供します。
しかし、TypeScriptの文脈では、これらのオブジェクト型はほとんど使用されません。なぜなら、これらのオブジェクト型はプリミティブ型とは異なる振る舞いをする可能性があるからです。例えば、プリミティブ型のstringとStringオブジェクトは、===演算子で比較すると等しくないと評価されます。これは、プログラムの予期しないバグを引き起こす可能性があります。
そのため、TypeScriptではプリミティブ型(number, string, boolean, symbol)を使用することが推奨されています。これらの型はJavaScriptのプリミティブ型と直接対応しており、予期しない振る舞いを避けることができます。
まとめると
プリミティブ型の値: これらの値(例えば、文字列や数値)は不変で、一度作成されると変更することはできません。新しい値を作成すると、新しいメモリ領域が確保され、その新しい値がそこに格納されます。
オブジェクト型の値: オブジェクトは変更可能で、そのプロパティの値を追加、更新、削除することができます。しかし、オブジェクト自体(つまり、オブジェクトのメモリアドレス)は不変で、一度作成されたオブジェクトを別のオブジェクトに「変更」することはできません。
したがって、プリミティブ型とオブジェクト型の主な違いは、プリミティブ型が不変であるのに対し、オブジェクト型はそのプロパティを変更することができるという点です。しかし、どちらの型でも、一度作成された値やオブジェクト自体を直接「変更」することはできません。新しい値やオブジェクトを作成すると、新しいメモリ領域が確保され、その新しい値やオブジェクトがそこに格納されます。