自作コンパイラの部屋 > オブジェクト指向プログラム言語としてのJavaScript > 14.コンストラクタとメソッド

14.コンストラクタとメソッド

 一般的に(つまりJavaScriptに限らず色々な言語では)クラスはプロパティ(メンバー変数)とメソッド(メンバー関数)を持つことになっています。これらのうちプロパティについては、前節で説明したとおりです。つまり JavaScript はオブジェクトのプロパティをサポートします。
 前に述べたように、JavaScriptは関数もオブジェクトの一種であり、オブジェクト同様変数に代入することができます。この性質を利用して、JavaScriptのメソッドを定義することができます。
 メソッドの実例として、Pointクラスのメソッド moveTo(x, y) と toString() という二つのメソッドを追加してみます。それぞれ、「点」を移動するメソッド、Pointクラスのオブジェクト(インスタンス)を表示用に文字列変換するメソッドです。

    // moveTo を関数として定義。名前は何でも良いが、
    // Point_をつけておくと分かりやすい
    function Point_moveTo(x, y) {
        this.x = x;    // プロパティ x を変更
        this.y = y;    // プロパティ y を変更
        return this;   // 自分自身を返すようにすると便利
    }
    function Point_toString() {     // toString を関数として定義
        return "Point(" + this.x + ", " + this.y + ")";
    }
    function Point(x, y) {
        this.x = x;
        this.y = y;
        this.moveTo = Point_moveTo;     // メソッド moveTo を設定
        this.toString = Point_toString; // メソッド toString を設定
    }
    var p = new Point(10, 20);   // Pointオブジェクトを生成
    document.writeln("p = ", p); // 表示。toStringメソッドが暗黙に呼ばれる
    p.moveTo(30, 100);           // 移動。moveToメソッドの明示的な呼び出し
    document.writeln("p = ", p);

実行結果:

 上図のように、メソッドを定義するためには、

  1. メソッドを関数として定義する
  2. コンストラクタにより、関数をプロパティとして代入する

という二段階を踏むことになります。

 これで絶対に悪いという訳ではないのですが、オブジェクト(インスタンス)ごとにメソッドのポインタを持つのは、メモリ効率が悪いと思われるかもしれません。 ことに、メソッドの種類とインスタンスの数が多い場合には、メモリが余計に必要です。
 この問題を克服するために、JavaScriptでは prototype という特別なプロパティを用います。

15.prototypeプロパティ

目次