prototypeでメソッドを定義するのは、コンストラクタにメソッドを記述するとメモリが食うことはわかるのですが、
コンストラクタに定義したプロパティとメソッドが、prototypeで重複して定義していなければ、prototypeに定義したプロパティメソッドをprototype参照を使わないで使用できますし(それでもオブジェクトのインスタンスからしか参照できないですが)
Rectangle.getArea()のように定義する機会はどうなのでしょうか?
混乱して困っています。
実際、Rectangle.getArea()のようなオブジェクトからの参照の使い方をしているのは、標準グローバルオブジェクトでは主に
各オブジェクトのprototypeや継承しているもの
StringオブジェクトのfromCharCode()
Numberオブジェクトの計算に使うもの
だと思っているのですが、
文章がおかしくなってすみません。
function Rectangle(w, h) {
this.width = w || 0, this.height = h || 0;
}
// 2つのメソッドの違い
Rectangle.getArea = function() { return this.width * this.height; };
Rectangle.prototype.getArea = function() { return this.width * this.height; };
// テスト
var r = new Rectangle(10, 10);
質問文が混乱しているので「どのような場合にprototypeにメソッドを定義するべきなのでしょうか?」という質問だと仮定して回答させていただきます。
仕組みはともかくとしてprototypeを使ったオブジェクト指向を利用する場合、以下の2点を認識しておけばいいと思います。
・オブジェクトに設定したメソッドは、そのオブジェクトからしか使えない。(newして作成したインスタンスからは使えない)
・オブジェクトのprototypeに設定したメソッドは、そのオブジェクトからnewして作成したインスタンスで使える。
質問にある例ですと、インスタンスのwidth*heightを求めることが目的の動作のようなのでRectangle.prototype.getAreaを設定すべきです。
(Rectangle.getAreaのメソッドは、インスタンスrから呼び出すことは出来ません)
以下に、オブジェクトに定義されたメソッドとprototypeに定義されたメソッドがどう違うのかのサンプルコードを示しますので参考にしてください。
function Obj() {} Obj.fncStatic = function () { alert('Static'); }; Obj.prototype.fncInstance = function () { alert('Instance'); }; //オブジェクトから直接メソッドを呼ぶ Obj.fncStatic(); //Obj.fncInstance(); // ※1エラー //オブジェクトからインスタンスを作成し、 //インスタンスのメソッドを呼ぶ var obj = new Obj(); //obj.fncStatic(); // ※2エラー obj.fncInstance();
※1:「Obj.fncInstance」なんてものは定義されていないので、エラー。
※2:newは、新しいオブジェクトを作成して、そこから親オブジェクトのprototypeが見えるように設定します。
このとき、prototype以外は作成されたオブジェクトから見えるように設定されません。
よって……
→objはObj.fncStaticを見つけることに失敗します。
→objはObj.prototype.fncInstanceを見つけることには成功します。
質問文が混乱しているので「どのような場合にprototypeにメソッドを定義するべきなのでしょうか?」という質問だと仮定して回答させていただきます。
仕組みはともかくとしてprototypeを使ったオブジェクト指向を利用する場合、以下の2点を認識しておけばいいと思います。
・オブジェクトに設定したメソッドは、そのオブジェクトからしか使えない。(newして作成したインスタンスからは使えない)
・オブジェクトのprototypeに設定したメソッドは、そのオブジェクトからnewして作成したインスタンスで使える。
質問にある例ですと、インスタンスのwidth*heightを求めることが目的の動作のようなのでRectangle.prototype.getAreaを設定すべきです。
(Rectangle.getAreaのメソッドは、インスタンスrから呼び出すことは出来ません)
以下に、オブジェクトに定義されたメソッドとprototypeに定義されたメソッドがどう違うのかのサンプルコードを示しますので参考にしてください。
function Obj() {} Obj.fncStatic = function () { alert('Static'); }; Obj.prototype.fncInstance = function () { alert('Instance'); }; //オブジェクトから直接メソッドを呼ぶ Obj.fncStatic(); //Obj.fncInstance(); // ※1エラー //オブジェクトからインスタンスを作成し、 //インスタンスのメソッドを呼ぶ var obj = new Obj(); //obj.fncStatic(); // ※2エラー obj.fncInstance();
※1:「Obj.fncInstance」なんてものは定義されていないので、エラー。
※2:newは、新しいオブジェクトを作成して、そこから親オブジェクトのprototypeが見えるように設定します。
このとき、prototype以外は作成されたオブジェクトから見えるように設定されません。
よって……
→objはObj.fncStaticを見つけることに失敗します。
→objはObj.prototype.fncInstanceを見つけることには成功します。
回答ありがとうございます。
インスタンスとstaticなプロパティ、メソッドで悩んでいたようです。
メソッドについては理解できましたが、
プロパティをカプセル化できないのがプロトタイプベースの言語にとっては仕方がないのでしょうか。
回答ありがとうございます。
インスタンスとstaticなプロパティ、メソッドで悩んでいたようです。
メソッドについては理解できましたが、
プロパティをカプセル化できないのがプロトタイプベースの言語にとっては仕方がないのでしょうか。