Javascriptのprototypeの理解について困っています。


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);

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2010/04/10 09:12:47
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:ku__ra__ge No.2

回答回数118ベストアンサー獲得回数40

ポイント100pt

質問文が混乱しているので「どのような場合に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を見つけることには成功します。

id:pochi1234

回答ありがとうございます。

インスタンスとstaticなプロパティ、メソッドで悩んでいたようです。

メソッドについては理解できましたが、

プロパティをカプセル化できないのがプロトタイプベースの言語にとっては仕方がないのでしょうか。

2010/04/10 09:12:11

その他の回答1件)

id:ku__ra__ge No.2

回答回数118ベストアンサー獲得回数40ここでベストアンサー

ポイント100pt

質問文が混乱しているので「どのような場合に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を見つけることには成功します。

id:pochi1234

回答ありがとうございます。

インスタンスとstaticなプロパティ、メソッドで悩んでいたようです。

メソッドについては理解できましたが、

プロパティをカプセル化できないのがプロトタイプベースの言語にとっては仕方がないのでしょうか。

2010/04/10 09:12:11
  • id:edvakf
    カプセル化、できないことはないですよ。

    var Constructor = function() {

    var foo;

    var getFoo = function() {
    return foo;
    }

    var setFoo = function(bar) {
    foo = bar;
    }

    }

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません