xrea-banner xreaad

Hello, prototype chain!

namespace kilrey; / JavaScript / 基本 / Hello, prototype chain!

前のページ(Hello, scope chain!)へ / 次のページ(Hello, script!)へ

プロトタイプ・チェーンについて説明します。 スコープ・チェーン以上に判り難いと思いますが、頑張ってください。

new によって生成したオブジェクトが対象です。 まずはサンプルを見て下さい。 (Hello, prototype chain! Sample 1)

<html>
  <head>
    <script type="text/javascript">
      function func(){
        this.message = "Hello, prototype!";
      };
      var obj = new func();
      func.prototype.greet = function(){
        alert(this.message);
      };
      obj.greet();
    </script>
  </head>
</html>
    

ここには

      func.prototype.greet = function(){
        alert(this.message);
      };
    

というように prototype プロパティに greet を設定しています。 この prototype が今回の主役です。 サンプルの実行結果を見ていただけば判るように、

      obj.greet();
    

で実際に実行されているのは func.prototype.greet です。 つまり、オブジェクトのプロパティを参照した場合は

  • そのオブジェクトのプロパティ
  • そのオブジェクトを生成した関数のprototypeのプロパティ
  • そのオブジェクトを生成した関数のprototypeを さらに生成した関数のprototypeのプロパティ
  • ...

というように順にたどっていって最初に発見されたものが返されます。


In Deep

Firefox ではそれとは別に __proto__ というプロパティもあります。 __proto__ と prototype は

そのオブジェクトを生成した関数のprototype == そのオブジェクトの__proto__
    

という関係にあります。 (Hello, prototype chain! Sample 2)

<html>
  <head>
    <script type="text/javascript">
      function func(){
        this.message = "Hello, __proto__!";
      };
      var obj = new func();
      obj.__proto__.greet = function(){
        alert(this.message);
      };
      obj.greet();
    </script>
  </head>
</html>
    

私はこちらの方が判り易いのではないかと思うのですが、 IE や Opera など、他のブラウザは対応していないので 互換性を考えるならあまり使わない方が良いでしょう。

前のページ(Hello, scope chain!)へ / 次のページ(Hello, script!)へ