prototypeの使い方

はじめに

javascriptの属性にprototypeと言うものがある.いまいち使い方が良くわからないので,色々試してみた.なお,実行結果はFirebird1.5.0.1で確認している.

インスタンス毎にメソッドを追加

まずクラスBirdを定義してインスタンスを二つostrichpenguinを作った.javascriptの場合,インスタンス単位に独自のメソッドを定義できるので,インスタンスostrichにメソッドrunを付け加えてみた.インスタンスpenguinにはメソッドrunはない.

以下ののsam.htmlをFirefoxで開くと,JavaScriptコンソールに以下のエラーを表示する.メソッドrunを定義しているのはインスタンスostrichのみであり,同じクラスからできていてもインスタンスpenguinには同名のメソッドが存在しないためである.

penguin.run();  エラー: penguin.run is not a function

<!-- sam.html -->
<html>
  <body>
    <script type="text/javascript">
      function Bird(name){
        this.name=name;
      }

      var ostrich=new Bird("ダチョウ");
      var penguin=new Bird("ペンギン");

      ostrich.run=function(){ //インスタンス`ostrich`にのみメソッド`run`を定義
        document.write(this.name+"は速く走るぜ!<br/>");
      }
      ostrich.run();
      penguin.run(); //エラー: penguin.run() is not a function
    </script>
  </body>
</html>

これは,インスタンスpenguinにメソッドを定義しても同じである.インスタンスpenguinにメソッドswimを定義してみた.この場合はインスタンスostrichはメソッドswimを持っていないため,エラーになる.

<!-- sam.html-->
<html>
  <body>
    <script type="text/javascript">
      function Bird(name){
        this.name=name;
      }

      var ostrich=new Bird("ダチョウ");
      var penguin=new Bird("ペンギン");

      ostrich.run=function(){
        document.write(this.name+"は速く走るぜ!<br/>");
      }
      ostrich.run();
      // penguin.run();  エラー: penguin.run is not a function

      penguin.swim=function(){
        document.write(this.name+"は速く泳ぐぜ!<br/>");
      }
      ostrich.swim(); //エラー: ostrich.swim is not a function
      penguin.swim();
    </script>
  </body>
</html>

prototype属性を使う

prototype属性にメソッドを追加することで,すでに生成したインスタンスも含め,新しいメソッドを追加できる.クラスBirdの属性prototypeにメソッドflapを付け加えると,それ以前に作成していたインスタンスostrichpenguinでもメソッドflapが使えるようになる.

<!-- sam.html -->
<html>
  <body>
    <script type="text/javascript">
      function Bird(name){
        this.name=name;
      }

      var ostrich=new Bird("ダチョウ");
      var penguin=new Bird("ペンギン");

      ostrich.run=function(){
        document.write(this.name+"は速く走るぜ!<br/>");
      }
      ostrich.run();
      // penguin.run();  エラー: penguin.run is not a function

      penguin.swim=function(){
        document.write(this.name+"は速く泳ぐぜ!<br/>");
      }
      // ostrich.swim();  エラー: ostrich.swim is not a function
      penguin.swim();

      Bird.prototype.flap=function(){ //属性prototypeにメソッドflapを追加
        document.write("羽ばたくぜ.でも飛べないのさ.だって"+this.name+"だから<br/>");
      }
      ostrich.flap(); //ostrichもメソッドflapが使える
      penguin.flap(); //penguinもメソッドflapが使える
    </script>
  </body>
</html>

javascriptがメソッドを以下の順番で探すためである.

  1. インスタンスの同名メソッド
  2. クラスのprototype属性から同名のメソッド

ちなみに,ostrich.prototype.flapBird.flapはエラーとなる.

ostrich.prototype.flap=function(){
  document.write("羽ばたくぜ.でも飛べないのさ.だって"+this.name+"だから<br/>");
}
エラー: ostrich.prototype has no properties

Bird.flap=function(){
  document.write("羽ばたくぜ.でも飛べないのさ.だって"+this.name+"だから<br/>");
}
ostrich.flap();
エラー: ostrich.flap is not a function