JavaScriptのオブジェクト指向:プロトタイプをきちんと理解する

白石俊平(あゆた)
2008-03-12 17:00:00
  • このエントリーをはてなブックマークに追加

プロトタイプによって解決!

 JavaScriptでは、こうした問題を解決するための仕組みとして、「プロトタイプ」という概念が用意されています。

 プロトタイプとは、以下のような特徴を持つオブジェクトです。

  • プロトタイプの実体は、コンストラクタ関数が持つprototypeプロパティ
  • 同じコンストラクタを持つオブジェクト間で共有される
  • オブジェクトのメンバを参照すると、「オブジェクト→オブジェクトのプロトタイプ」の順で検索される

 これだけではわかりにくいと思うので、Personクラスを作り直す過程を例に挙げて説明しましょう。まず、問題となっているhello()メソッドを除外した形でPersonを作成します。

function Person(name) {
  this.name = name;
}
// 白石オブジェクトを作成しておく
var shiraishi = new Person("白石");

 当然ながら、以下の呼び出しは失敗します。Personクラスにhello()と言う名前のメソッドが存在しないためです。

// 存在しないメソッドの呼び出し
shiraishi.hello();

 そこでプロトタイプの出番です。

 プロトタイプの実体は、コンストラクタ関数が持つprototypeプロパティであり、自由に変数や関数を追加することができます。プロトタイプにhello()メソッドを追加してみましょう。

Person.prototype.hello = function() {
  alert("こんにちは。私の名前は" + this.name + "です。");
};

 ここで再度、「shiraishi.hello()」の呼び出しを行ったと仮定しましょう。すると、JavaScriptランタイムはhello()と言う名前のメソッドを、以下のように検索します。

  1. "hello"と言うメンバをshiraishiオブジェクトから参照しようとする
  2. オブジェクトには"hello"が存在しないので、プロトタイプから参照しようとする
  3. プロトタイプには"hello"が存在するので、hello()の呼び出しは成功する!

 そして、同じコンストラクタから生成されたオブジェクトが複数有ったとすると、それらは同じプロトタイプを共有します。よって、同じコードからなる関数オブジェクトが重複して生成される、という領域の無駄遣いを抑えることができます。

 今までの説明を図で表すと以下のようになります。

プロトタイプ使用後

まとめ

 プロトタイプという仕組みが、どのように働くかがお解りでしょうか?いまいち良く解らない、と言う方は、とにかく次の文章を覚えておくと良いでしょう。

「オブジェクトのメンバは、オブジェクト→プロトタイプの順に検索される」

 プロトタイプは非常に単純ですが、素晴らしく柔軟な仕組みです。きちんと理解して使いこなせるようになっておきましょう。数多くのJavaScriptフレームワークでは、プロトタイプを駆使した様々なテクニックが使用されています。

 次回も、オブジェクト指向に関するお話です。これまでお話しした話題をまとめて、「JavaScriptクラスの作り方」をもう一度しっかり解説します。

このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。 これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。
Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。
[ 閉じる ]