JavaScriptのオブジェクトについての話題を扱って来ましたが、JavaScriptのデータ型(type)には大きく分けてプリミティブ型とオブジェクト型に大別されます。
プリミティブ型には数値・文字列・論理値・null・undefinedがあり、オブジェクト型はそれ以外のオブジェクトということになります。プリミティブ型はプロパティとメソッドを持たない単純なデータですが、オブジェクトはプロパティ(値)とメソッド(操作)の集まりとなっています。
プリミティブ型とオブジェクト型について比較して見ていきましょう。
プリミティブ型とは?オブジェクト型とは?
プリミティブ型とオブジェクト型の違いは、プリミティブ型を持つ変数は、その変数自体の中にデータを保持するということです。
オブジェクトに関連つけられた変数には実際にはオブジェクトは含まれれいません。オブジェクトが格納されているメモリへの参照が格納されています。ですから、オブジェクトとして宣言された変数には、そのオブジェクトを示すコピーはありません。
このあたりの違いを順に見ていきましょう。
プリミティブ型
まずはプリミティブ型から見ていきます。いくつかの変数を定義して見ていきましょう。
次のようにスクリプトファイルを書いて、前と同様にJavaScriptコンソールで実行していきます。
var a = 20;
var b = a;
a = 100;
console.log(a);
console.log(b);
変数aを定義し、変数bにそのaを代入しています。続けてaに100を代入して、それぞれをconsole.logで表示しています。
JavaScriptコンソールには次のように表示されます。
思っていた数字が表示されたでしょうか? bにaを代入した時には20で、aに100を代入したことが影響していません。先ほど説明したように、格納先のメモリを参照するのではなくデータのコピーがそのまま入っていると言うことがこれで確認できます。
オブジェクト型
今度はオブジェクト型で同様な操作をしてみようと思います。
次のようなスクリプトを書いてみます。
var obj1 = {
name: 'Edward',
age: 20
};
var obj2 = obj1;
obj1.age = 100;
console.log(obj1.age);
console.log(obj2.age);
obj1という辞書型のオブジェクトを定義しています。以降の操作はプリミティヴで行ったものと同じような操作であるのはわかると思います。
JavaScriptコンソールには次のように表示されます。
先ほどと違って、両方とも同じ値になっています。書き換えたオブジェクトの値が反映されて表示されている訳です。これはオブジェクト自体がコピーされたのではなく、データの保存先メモリのアドレスを参照している訳です。ここでは、obj1もobj2も同じメモリのアドレスを保持していることになります。だから同じ値になっている訳です。
プリミティブ型とオブジェクト型の違いを関数の操作で確認
先ほどの操作で、プリミティブ型とオブジェクト型の違いは確認できたと思いますが、ここではまとめ的にプリミティブ型とオブジェクト型を関数で一緒に扱ってみます。
次のようなコードを書いてみます。
var age = 20;
var obj = {
name: 'エドワード',
city: 'セントラル'
};
function change(a, b) {
a = 26;
b.city = 'リゼンブール';
}
change(age, obj);
console.log(age);
console.log(obj.city);
最初にageとobjを定義しています。それぞれプリミティブ型とオブジェクト型です。ここでchange()関数を定義していきます。引数a,bを用意して、二つのパラメータを用意しています。aの値を26に、bの値をcityとしてリゼンブールにしています。
この関数を呼び出して、console.logでageとobj1.cityを表示しています。
JavaScriptコンソールには次のように表示されます。
関数はaの値を26に変更していますが、ageはプリミティブ型なので20のまま表示されています。objはオブジェクト型なので、obj.cityはb.cityの参照先となって与えられたパラメータに変更されます。したがって、セントラルからリゼンブールに変わっているのがわかります。
関数内でプリミティブ型とオブジェクト型を定義すると、プリミティブ型はデータのコピーが渡されるので、関数内での変更は関数の外部の変数には影響しませんが、オブジェクト型は参照を渡すので、関数内での変更が外部の変数に反映されます。
まとめ
ここではJavaScriptのデータ型(type)であるプリミティブ型とオブジェクト型を扱いました。
プリミティブ型は数値・文字列・論理値・null・undefinedで、オブジェクト型はそれ以外のオブジェクトです。
プリミティブ型はプロパティとメソッドを持たない単純なデータですが、オブジェクトはプロパティ(値)とメソッド(操作)の集まりです。
プリミティブ型の変数は、その変数自体の中にデータそのものを保持しますが、オブジェクトに関連つけられた変数は、オブジェクトが格納されているメモリへの参照が格納されています。ここでは、この違いを操作で見てきたことになります。