プリミティブ型とオブジェクト型の違い
constでオブジェクト型のものは値の中身を変更することができ、プリミティブ型は変更ができない点に関して、詳細に説明します。
内部的に見ると、変数は特定のメモリのアドレスを格納しますが、プリミティブ型とオブジェクト型で挙動が異なります。
まずプリミティブ型は、下の図で説明すると、let name1 = 'tarou'とすると、tarouがメモリの特定の場所(0x0001)に格納されます。格納された場所を表すものをアドレスと言うのですが、name1が値を保持する0x0001に紐づいて、別の場所に保存されます(0x0002)。
この時let name2 = name1とコピーしたとすると、name2も0x0001というアドレスを参照していることを0x0003というアドレスに格納されます。

その後name1 = 'jirou'と上書きしたとすると、jirouが別のアドレス(0x0004)に格納され、name1の参照先がそのアドレスに書き換えられます。ですので、name2の値は変わりません。このようにメモリに格納された値自体を変えることができません。

一方でオブジェクト型は、let product1 = {...}と定義した際に、各プロパティの値が各アドレス(0x0001, 0x0002)に格納され、その値に対応するkeyの情報も各アドレス(0x0003, 0x0004)に格納され、それら全てのプロパティを参照しているアドレスを一つのアドレス(0x0005)に格納し、それをproduct1が参照する(0x0006)ようになっています。

この時、let product2 = product1とコピーしたとすると、product2も0x0005というアドレスを参照していることを0x0007というアドレスに格納されます。

ここで、product1.name = 'みかん'とプロパティの値を変更したとします。そうすると、みかんという値が別のアドレスに格納され、nameの参照アドレスが変更されます。ですので、product2のnameもみかんに変わります。また、constで定義した際に、なぜプロパティを変更できるのかというと、constは内部的な挙動として、定義した定数の参照先アドレスを変えるとエラーとなるので、参照先の参照先が変更する場合はエラーとなりません。

まとめると、
プリミティブ型の変数は値をコピーした際に、元の値を上書きしても、コピー先は変わらない。constで定義したものは値を変更することができない。
オブジェクト型の変数は値をコピーした際に、元の値(keyや要素)を変更した際に、コピー先も変わる。constで定義しても、keyや要素を変更することができる。
Last updated