prototypeは、ビルトイン、ユーザ定義に関わらず全てのFunction objectが持つビルトインプロパティです。そしてそのタイプはobjectです。そのprototypeプロパティが持つプロパティは、そのFunction objectからnew演算子で作られる全てのインスタンスから、そのプロパティ名で参照することができます。
例14
MyClass = function (num) {
this.x = num;
}
MyClass.prototype.getX = function () { //getXメソッドをMyClass.prototypeに定義
return this.x;
}
myObj1 = new MyClass(5); //MyClassコンストラクタでmyObj1というインスタンスを生成
trace(myObj1.getX()); //出力:5
4~6行目でMyClass.prototypeに定義されたgetXメソッドは、最後の行にあるように、myObj1からそのまま参照できます。つまり、以下のようにgetXをmyObj1に直接定義した場合と同じように、myObj1がgetXメソッドを使用できるようになるということです。
例15
myObj1.getX = function () {
return this.x;
}
trace(myObj1.getX()); //出力:5
では例14の4~6行目と例15の1~3行目の違いは何でしょう。
例15のように書くとMyClassコンストラクタから作られる他のインスタンスは当然getXを持ちません。つまり同クラスの他のインスタンス、例えばmyObj2にもgetXメソッドを持たせたい場合、
myObj2.getX = function () {
return this.x;
}
というようにそちらにもgetXメソッドを定義しなくてはなりません。
それに対して例14の場合は、それぞれのインスタンスに個別にgetXメソッドを定義しなくてもMyClassコンストラクタから作られる全てのインスタンスでgetXが有効になり、そしてそれはメモリー消費を抑えることにも繋がります。つまり、
例16
//例14に続けて
myObj2 = new MyClass(8);
trace(myObj2.getX()); //出力:8
ということが可能で、またそれは、このようにクラスのインスタンス全てに同じプロパティを持たせたい場合に非常に有効な手段であるわけです。
ビルトイントップレベルFunction objectのprototypeプロパティも同様に扱うことができます。以下はその例です。
例17
MovieClip.prototype.rotate = function (degree) {
this._rotation += degree;
}
//ステージ上にmovieclip, mc1とmc2が置かれているとして
mc1.onEnterFrame = function () {
this.rotate(2);
}
mc2.onEnterFrame = function () {
this.rotate(10);
}
これで、mc1が毎フレーム2度ずつ、mc2が毎フレーム10度ずつ回転します。つまり、ビルトイントップレベルFunction objectの一つであるMovieClipのprototypeプロパティに定義したrotateメソッドが全てのmovieclipに対して有効になったわけです。
では次に、コンストラクタのprototypeに定義されたプロパティをインスタンスが参照する仕組みについて見てみましょう。