■ プリミティブ型とオブジェクト型
JavaScriptのデータ型(Type)は、プリミティブ型とオブジェクト型に大別されます。
プリミティブ型 数値・文字列・論理値・null・undefined
オブジェクト型 その他オブジェクト
さて、オブジェクトとはプロパティ(値)とメソッド(操作)の集まりです。たとえば、JavaScriptでは配列はArrayオブジェクトです。
var array = ["blue", "green", "red"]; // lenghtプロパティ console.log(array.length) //=> 3 // reverse()メソッド array.reverse(); console.log(array); //=> ["red", "green", "blue"]
それに対してプリミティブ型とはプロパティとメソッドを持たない単純なデータです。たとえば数値は「1」「3.14」といった数、文字列は「’Hello’」や「’こんにちは’」といった一連の文字、論理値は「true(真)」「false(偽)」のどちらかの値です。
var num = 3; // 数値型 var str = “Hello”; // 文字列型 var isOK = true; // 論理値型
■ ラッパーオブジェクト
なお、数値、文字列、論理値といったプリミティブ型をオブジェクトとして扱うデータ型が用意されています。それれらの型をラッパーオブジェクトと呼びます。
Number
String
Boolean
これらのオブジェクトを明示的に生成するにはコンストラクタを使用します。コンストラクタの名前はオブジェクト名と同じです。
var strObj = new String("Hello”); // Stringオブジェクトを生成 var numObj = new Number(3); // Numberオブジェクトを生成 var isOKObj = new Boolean(true); //Booleanオブジェクトを生成
■ ラッパーオブジェクトへの変換は自動で行われる
プリミティブ型はプロパティとメソッドを持たないと説明しましたが、実際にはプリミティブ型の値のプロパティやメソッドにアクセスできます。次の例は、文字列に対して、String型のlengthプロパティ、およびcharAt()メソッドにアクセスしています。
var str = “Hello”; len = str.length; // lenghtプロパティ c = str.charAt(0) // charAt()メソッド
実は、プリミティブ型の値に対して、対応するラッパーオブジェクト(文字列の場合にはString型)のプロパティやメソッドにアクセスすると、一時的にラッパーオブジェクトに変換されるのです。
■ プリミティブ型とラッパーオブジェクトの値の比較
プリミティブ型と値、それに対応するラッパーオブジェクトの型の値を比較する場合に、「==」を使用すると値の比較となります。たとえば文字列型とString型の比較では、文字列が同じ場合にはtrueとなります。
var str = “Hello”; var strObj = new String("Hello”); isSame = (str == strObj); //=> true
それに対して「===」演算子を使用した場合、厳密な比較となり、文字列が同じであったもfalseとなります。
isSame = (str === strObj); //=> false
■ 変数について
変数とは、もちろん値を格納する領域のことですね。変数名と値を結び付けることを「変数に値を代入する」などと言います。
var num = 3; // (1)数値型 var array = [1, 3, 4]; // (2)Arrayオブジェクト(配列)
上記の(1)はプリミティブ型である数値の「3」を変数numに、(2)は3つの要素を持つArrayオブジェクト(配列)を変数arrayに代入しています。
どちらも、変数には値そのものが格納されるというイメージでとらえないでください。変数の場所を指し示すリファレンスと呼ばれる値が格納される考えるとよいでしょう。
◎図 h1
あるいは変数名は値に付けられたタグのようなイメージでとらえてもかまいません。
◎図 h2
このことを頭に入れておくと、変数を別の変数に代入した場合の動作がわかりやすくなります。次の例を見てみましょう。
var a = 1; var b = a; // (1) a = a + 2; // (2) a:3、b:1
この場合、(1)の段階では変数aも変数bも「1」という同じ値を指し示しています。
◎図 h3
(2)では変数aは新たに「3」という値を指し示しますが、変数bは「1」のままです。
◎図 h4
Arrayオブジェクトなどのオブジェクト型を変数に代入した場合も考え方は同じです。
var a1 = [1, 3, 4]: var a2 = a1; // (1) var a1 = [5, 6]; // (2)a1: [5, 6]、a2:[1, 3, 4]
(1)の段階では変数a1、a2ともに「 [1, 3, 4]」を指し示していますが、(2)の段階ではa1とa2は異なる配列を指し示しています。
◎図 h5
■ ミュータブルな型とイミュータブルな型
さて、データ型にはミュータブル(変更可)とイミュータブル(変更不可)という分類の方法があります。数値や文字列などのプリミティブ型はイミュータブルです。また、StringやNumberといったラッパーオブジェクトもイミュータブルです。
それに対してArrayオブジェクトやObjectオブジェクト、日付時刻を管理すうrDateオブジェクトなどはミュータブルなオブジェクトです。
ここで、数値型などは変数に対して演算を行って、また同じ変数に格納できるので値を変更できるミュータブルなのでは?と考える方もいるでしょう。
var num = 1; num = num + 3; console.log(num); //=> 4
上記の例は「1」という数値を変更しているわけではありません。「num + 3」で新たに「4」という数値を生成して、そのリファレンスを変数numに再代入しているのです。
◎図 h6
あるいは「4」という数値に「num」というラベルを設定しなおしていると考えてもいいでしょう。
別の例として、イミュータブルな型である文字列およびString型は後から値を変更できません。
var str = "Hello"; str[0] = "A”; // 1文字目を”A”に変更しようとしても console.log(str); // “Hello” ←変更は無視される
一方、ミュータブルな型であるArrayオブジェクトは、後から要素の値を変更できます。
var array = [1, 3, 4]; array[0] = 5; console.log(array); //=> [5, 3, 4]
またDateオブジェクトもミュータブルな型ですのでメソッドを実行して値を変更できます。
var theDate = new Date(); // 現在の日時を管理する theDate.setFullYear(1959); // setFullYear()メソッドを使用して年を1959に変更