JavaScriptでもオジェクト指向プログラミングは可能だが、クラスの実現方法はJavaやC#とはずいぶんと異なった印象を受ける。
JavaやC#のオブジェクト指向が「クラスベース」と呼ばれるのに対し、
JavaScriptのオブジェクト指向は「プロトタイプベース」と呼ばれる。
JavaScriptではどのようにクラスを作成するのかを見ていこう。
もっとも単純なクラス
以下のように書く。
MyClass = function(){};
このように、JavaScriptにおけるクラスとは関数オブジェクトの定義に他ならないことがわかる。
こうして定義された関数オブジェクトはコンストラクタ関数と呼ばれる。
JavaScriptでは通常、変数名は小文字始まりとするが、コンストラクタ関数の場合は普通の関数との区別のため大文字始まりとするのが慣例のようだ。
新しいクラスのオブジェクトを生成するには、以下のようにnew演算子を使ってコンストラクタ関数を呼び出す。
var myClass = new MyClass();
new演算子を使って関数オブジェクトを呼び出すと、内部では以下の流れで処理が行われている。
- 新しいオブジェクトを生成する。
- コンストラクタ関数を呼び出す。
コンストラクタ関数内ではthisキーワードを使って新規作成したオブジェクトにアクセスできる。
この性質を利用して、オジェクトにメンバ関数を追加していくことになる。
メンバ変数を追加する
メンバ変数を追加するにはコンストラクタ関数を以下のようにする。
MyClass = function(nm,ag){ this.name = nm; this.age = ag; };
このように書くことで、MyClassというコンストラクタ経由で作られたオブジェクトには
nameとageというプロパティが含まれることになる。
メソッド(メンバ関数)を追加する
以下のように書く。
MyClass = function(nm,ag){ this.name = nm; this.age = ag; }; // メソッドの追加 MyClass.prototype.sayHello = function(){ alert("Hello MyClass!!"); }
メソッドは、関数オブジェクトのprototypeというプロパティに追加している。
このprototypeは、関数オブジェクトが必ず持っているプロパティである。
そして、newによって作成されたオブジェクトは、そのコンストラクタ関数のprototypeへの参照を持っている。
このような性質があるから、インスタンスが異なってもクラスの共通の情報を参照できることになる。
メソッドのように、インスタンス毎に異なる値を持つ必要の無いものに関しては
クラス内で共通に参照されるプロトタイプオブジェクトに追加したほうがメモリの効率が良いので、このようなコードとなる。
複数のメソッドを定義するときは、オブジェクトリテラルを使って以下のように書くこともできる。
MyClass = function(nm,ag){ this.name = nm; this.age = ag; }; // メソッドの追加 MyClass.prototype = { sayHello:function(){ alert("Hello MyClass!!"); }, doSomething:function(){ alert("My name is " + this.name + ". I'm " + this.age + " years old."); } };
以上が、JavaScriptにおけるクラスの作成の手順となる。