JavaScriptがプロトタイプベースのオブジェクト指向言語ってどういうこと?

白石俊平
2008/03/21 19:00

今回はプロトタイプチェインの重要性を説明したいと思います。そのために、まずプロトタイプチェインを用いて擬似的なクラスの継承を行い、その上でObjectクラスが持つメンバについてもお話ししておきたいと思います。

Objectクラスは、全てのクラスの親となる

 ここまで来れば、オブジェクトのメンバ参照は、プロトタイプチェインの途中でメンバが見つからない場合、最終的には全てObject.prototypeを参照する、というのがお解りでしょう。プロトタイプチェインの終端は常にObject.prototypeなのですから。

 そう考えると、「あらゆるJavaScriptオブジェクトは、Object.prototypeが持つプロパティを呼び出し可能」ということになります。これはさらにいえば、「Objectクラスは、あらゆるJavaScriptクラスの親である」と言い換えても良いと思います。

 このことから言えるのは次の二つです。

Objectクラスが持つメンバは、あらゆるオブジェクトから利用できる

 あらゆるオブジェクトがObject.prototypeを継承しているのですから、これは当然です。

 JavaScript(ECMAScript)では、Objectクラスは以下のようなメンバを持つと規定されています。

  • constructor・・・オブジェクトの生成元になったコンストラクタ関数
  • toString()・・・オブジェクトの文字列表現を返す
  • toLocaleString()・・・オブジェクトの(ロケールに対応した)文字列表現を返す
  • valueOf()・・・オブジェクトを変換した値を返す。例えばNumberクラスは数値、Booleanクラスは真偽値を返す。デフォルトではオブジェクト自身(this)が返る
  • hasOwnProperty(propName)・・・指定されたメンバを、オブジェクト自身が持っているかどうかを真偽値で返す。プロトタイプチェインは辿らない
  • isPrototypeOf(value)・・・このメソッドを呼び出したオブジェクトが、valueのプロトタイプチェインに含まれているかどうかを返す。
  • propertyIsEnumerable(propName)・・・指定されたメンバを、オブジェクト自身が列挙可能(for..inで取得できる)かどうかを真偽値で返す。プロトタイプチェインは辿らない

 あまり馴染みのないメソッドも多いかと思いますが、とりあえずこれらのメソッドはあらゆるオブジェクトに対して呼び出し可能です。是非試してみてください。

Object.prototypeにあとから追加したメンバも、あらゆるオブジェクトから利用できる

 JavaScriptはきわめて動的な言語なので、あらゆるオブジェクトに対してメンバを後から追加したり、削除したりすることが自由に行えます。そのため、例えばObject.prototypeに対して後からメンバを追加したりすると、あらゆるオブジェクトから即座にそのメンバに対してアクセスを行えるようになります。

// あらゆるJavaScriptオブジェクトがhello()を持つようになる
Object.prototype.hello = function() {
  alert("Hello");
};
// Stringクラスも、hello()を持つようになる
"abc".hello();

 ただしこれは、プログラムに対する影響が非常に広いので、あまりおすすめはできません。

記事の感想やご意見をコメントでお寄せください(CNET_IDログインが必要です)
ログイン パスワードを忘れた方  |  新規登録
米フォレスター・リサーチ社 シニアアナリスト Jeremiah K.Owyang氏を迎え、同氏が提唱するソーシャルテクノロジーを効果的に活用方法するための方法『POST』を日本で初めて紹介する注目のリアルイベント
  • 今日のトップ記事
  • 昨日
  • 2日前
  • 5日前
  • 6日前
  • 7日前
  • 新着記事
  • 人気記事
  • 特集
  • ブログ