基本型と参照型【JavaScript】

JavaScript
動点P
動点P

違う変数で定義されているのに一方が変わったらもう一方の変数の値まで変わってしまった!!

動点Qちゃん
動点Qちゃん

それはきっと参照型の変数を使ってるんですよpさん・・・

const a = ["イチゴ", "ミカン"];
const b = a;

b[0] = "スイカ";
console.log(a) // ["スイカ", "ミカン"]

こんな風にconstで定義した変数が、構ってないのに変更されてしまうことがあります。参照値渡しという言葉は知っていたんですが、まさかconstでこれが起きると思っておらず、2日くらい悩んでいました…。でもすごく基礎的なことなのでちゃんと勉強しておきます。

基本型と参照型

JavaScriptのデータ型には「基本型」「参照型」があります。

基本型・・・数値型(1、2…)、文字列(”お早う”、”hello”…)、真偽値型(true, false)、シンボル型、特殊型(null, undefined)

const a = 100;
const b = 200;
a = b;
console.log(a);//error

const c = "イチゴ";
const d = "ミカン";
c = d;
console.log(c);//error

基本型のデータは変数に直接格納されるので、定数として定義すると、他の変数を渡そうと思ってもエラーが出ます。(もちろんletならc=dで代入でき、cがミカンになります。)

参照型・・・配列([0, 1]、[“猫”, “犬”]…)、オブジェクト({a:dog, b: cat})、関数

const a = ["イチゴ", "ミカン"];
a[0] = "スイカ";
console.log(a) //["スイカ", "ミカン"]

const c = {dog:"bow", cat:"myaw"}
c.dog ="わん"; 
console.log(c) //{dog:"わん", cat:"myaw"}

参照型のデータの場合は値を格納しているアドレスが変数に格納されているので、そのアドレス先の値を変更されてしまうと、同じ場所を参照している変数も値が変わってしまいます。

なのでそもそも配列やオブジェクトはconstで定義しようが、キーを使ったりして簡単に内容の値は変更できます。

以下、変数を鹿くんの家クッキーちゃんの家にたとえてみた図。どちらもそのものではなく単なるアドレスなので、また要素を増やすことも簡単にできてしまいます。しかしアドレス同士は違うアドレスなので、鹿くんの家 = クッキーちゃんの家 みたいに違うアドレスを渡すことはconstの場合はできません。(letならできます。)

当たり前じゃないかと思うかもしれませんが、混乱してしまうのが、=で違う変数を割り当ててしまったときの影響なんですね。というわけでまた以下説明図です。

クッキーちゃんが、鹿くんの家をコピーしたつもりでそのアドレスごとコピーしてしまうというお話です。そしてアドレスは鹿くんの家なのに、その変数名は「クッキーちゃんの家」なので、自分の家だと思い込んだクッキーちゃんはやりたい放題。その結果、鹿くんの家のものが捨てられてしまいました。

このお話が、以下のコードで起きていることです。

const a = ["イチゴ", "ミカン"];
const b = a;

b[0] = "スイカ";
console.log(a) //["スイカ", "ミカン"]


const c = {dog:"bow", cat:"myaw"}
const d = c;

d.dog ="わん"; 
console.log(c) //{dog:"わん", cat:"myaw"}

bという変数を変更しただけなのに、aも変更されてしまった…それは同じアドレスのものを操作しているからということが言いたかったんですが、わかりやすかったでしょうか?

逆にこの性質を使って行列スタックなどの仕組みが出来ていたりしますよね。参照してわざとある変数の値を変える。こういうものにぶち当たってしまい、悩んでいたのでした…。

コメント