JavaScriptはPrimitive TypeとReference Typeという二つのデータ型を提供し、オブジェクトを除いた全てのものはPrimitiveな性格を持っている。
Primitive Type : 基本型/データの情報が入っている
Reference Type : クラス型/オブジェクト実体の場所情報入っている
Primitive Type (基本型)
Primitive Typeのデータは変数に割り当てられる時、メモリ上に固定された大きさで保存され、当該変数が原始データの値を保管する。 Primitive Typeのデータ型はすべて変数宣言、初期化、割り当て時に値が保存されたメモリ領域に直接的にアクセスする。 すなわち、変数に新しい値が割り当てられる場合、変数に割り当てられたメモリブロックに保存された値をすぐに変更する。
Primitive Typeの種類
- Boolean
- number
- String
- undefined
- BigInt
- シンボル
Primitive Typeの変数の複製
各変数の間でPrimitive Typeのデータをコピーする場合、データの値がコピーされる。
var x = 100;
var y = x;
x = 99;
console.log(y); // 100;
データの値をコピーするためconsoleを使う前にxを99に変わったが、以前の値である100をコピーしておいたので100が出力されることがわかる。
Reference Type (クラス型)
Reference Typeのデータは、大きさが決まっておらず、変数に割り当てることになると、値が直接当該変数に保存されることはできず、変数にはデータに対する住所が保存されている。変数の値が保存されたヒープメモリの住所を保存する。Reference Typeは変数の値が保存されたメモリブロックの住所を持っていてjavascriptエンジンが変数が持っているメモリアドレスを利用して変数の値に接近する。
Referece Typeの種類
Object ( array, function, object )
Reference Typeの変数の複製
各変数の間でReferece Typeのデータをコピーする場合、データの住所がコピーされる。
var x = { count : 100 };
var y = x;
x.count = 99;
console.log(y); // 99
変数xとyは同じ住所の値を持っている。したがって、同一のオブジェクトを指すことになる。
Primitive Type vs Reference Type
例 1
var list1 = [1, 2, 3]; // メモリ住所 : 8765e と仮定する
var list2 = [1, 2, 3]; // メモリ住所 : 9524d と仮定する
var isSame = list1 === list2; // 8765e === 9524d
console.log(isSame); // false
list1、list2の中の要素は同じだが、配列を新しく作り変えて変数に埋めているため、それぞれ新しいメモリ住所を作って保存し、その住所を参照して変数に該当する住所の値を保存するのと同じである。
したがって、結果はfalseとなる。
例 2
var list3 = [ 1, 2, 3];
var list4 = list3;
var isSame = list3 === list4;
console.log(isSame); // true
上の例題とは異なり、新しく配列を生成せずにlist3の位置値をそのままlist4に入れるのであるから、メモリ住所が同じ場合と言える。
したがって結果はtrueとなる。
例 3
var updateAge = function () {
this.age++;
}; // 'メモリ住所 : 4737d' と仮定する
var son = {
age : 3,
growUp : updateAge
};
var daugther = {
age : 7,
growUp : updateAge
};
var mother = {
age : 38,
growUp : updateAge,
children : [ son, daugther ]
};
var father = {
age : 38,
growUp : updateAge,
wife : mother,
children : [ son, daugther ]
};
// ### 例 3.1
if (father.growUp === son.growUp) { // 4737d === 4737d
console.log('成長可能');
} // output : 成長可能
// ### 例 3.2
if (father.children === mother.children) {
console.log('夫婦!');
} // falseなので、console.logが実行されない
例3.1の場合、updateAgeという変数のデータ値に関数の住所の値を保存した。仮想メモリアドレスが4737dという仮定の下にobjectは、当該データの住所の値を保存するため、father.growUpとson.growUpの値は同じ値になる。
したがって、結果はtrueにconsoleに'成長可能'が出力される。
例3.2の場合、同じ変数が埋められているが、オブジェクト内で配列を新たに作ってmother.childrenとfather.childrenは異なる住所の値を新たに割り当てられたため、住所の値が異なる。
したがって、結果はfalseにconsoleに何も出力されない。
参考
PR
不動産売却の時は LIFULL HOME'S へ!