文書の過去の版を表示しています。
クラス
厳密にはJavaScriptにクラスはない。機能の異なるオブジェクトは存在するが、それらは持っているプロパティやメソッドが異なっているだけで、オブジェクトの性質には違いはない。
コンストラクタ
Construct関数を不可視プロパティとして持っているオブジェクトは、Construct関数で定義されたプロパティを持つインスタンスを生成することができる。
Construct関数を持っているオブジェクトは、いくつかのグローバルオブジェクトと、ユーザが定義した関数オブジェクトである。関数を定義すると、定義された関数オブジェクトはコンストラクタとなり、その関数自身がConstruct関数となる。
標準のオブジェクト型
- Boolean
- Number
- String
- Array
- Object
- Function
- RegExp
- Date
var s = new String("a"); var d = new Date();
ユーザ定義のオブジェクト型
// クラス定義1 // コンストラクタ関数 function Greet() { // プロパティの定義 this.message = "hello"; // メソッドの定義 this.say = function() { return this.message; }; } // インスタンスの生成 var greet = new Greet(); // メソッドの呼び出し greet.say();
コンストラクタとして使う関数は、慣例として大文字で名前を定義する。
プロトタイプ
全てのオブジェクトは constructor というプロパティを持っている。これは自分を生成したコンストラクタ関数へのリファレンスである。
constructor は prototype というオブジェクトを持っている。あるオブジェクトに対して存在しないメソッドAが呼び出された時、自分のconstructor の prototype がメソッドAを持っていれば、それが実行される。
よってコンストラクタ関数の prototype に対してメソッドを定義すれば、そのメソッドを生成したインスタンスから呼び出す事ができる。また、prototype はインスタンス間で共有されるので無駄な関数オブジェクトが生成されることもない。(クラス定義1のようにコンストラクタ関数でメソッドを定義すると、コンストラクタを呼ぶたびに関数オブジェクトを作成するので無駄だが、prototype へのメソッド設定ならば一度で良いので無駄が無い)
このため、実際のプログラミングでは、メソッドは、prototype に定義し、プロパティはコンストラクタで定義するのが一般的である。
// クラス定義2 function Greet() { this.message = "hello"; } Greet.prototype.say = function() { return this.message } var greet = new Greet(); greet.say();
prototypeを丸ごと上書きして置き換えることもできます。
// クラス定義3 function Greet() { this.message = "hello"; } Greet.prototype = { say: function() { return this.message } }; var greet = new Greet(); greet.say();
prototypeを上書きした場合と、そうでない場合では厳密には異なるインスタンスを作成する。
プロトタイプチェーン
オブジェクトがプロパティを持っていなければ、コンストラクタの prototype からプロパティを探すが、その prototype も該当するプロパティを持っていなければ、さらにその prototype のコンストラクタの prototype からプロパティ探す。この仕組みをプロトタイプチェーンと呼ぶ。
プロトタイプチェーンを使うと継承のような事ができるが、実際に使われる事は少ない。
function Greet() { this.message = "hello"; } Greet.prototype.say = function() { return this.message } function NightGreet() { this.message = "good night"; } NightGreet.prototype = new Greet(); // Greetを継承 function JpNightGreet() { this.message = "おやすみなさい"; } NightGreet.prototype = new NightGreet(); // NightGreetを継承 // JpNightGreet型のインスタンス生成 var jpNightGreet = new JpNightGreet(); // Greet型のメソッドsayが呼び出される jpNightGreet.say();