JavaScriptにおける継承

JavaScriptのオブジェクトは、他のオブジェクト(またはnull)をプロトタイプとして利用することができる。
オブジェクトのプロパティが参照された際、そのプロパティをオブジェクト自身が保持していなければ、代わりにプロトタイプのプロパティが参照される。
さらにプロトタイプのオブジェクトがそのプロパティを保持していない場合には、プロトタイプのプロトタイプを参照する。(nullに行き着くまで繰り返す)
このようにオブジェクトが他のオブジェクトのプロトタイプとして連鎖していく仕組みをプロトタイプチェーン(prototype chain)と呼ぶ。
JavaScriptでは、このプロトタイプチェーンを利用して継承を行う。

 

コンストラクタ関数とnew演算子のみで継承

まずは、シンプルに基底となるオブジェクト(コンストラクタ)を元に新しいオブジェクト(インスタンス)を生成する方法で継承をしてみる。
※途中に出てくる”arguments”オブジェクトは、関数呼び出しのタイミングで生成されて呼び出し元から与えられた引数の値を配列で保持している特別なオブジェクト

上記のコードで継承を行っている部分は、”Cat.prototype = new Pet();”にあたる。
うまく動作するように見えるが、実際に実行すると”—–Cat—–“の出力の前に”基底オブジェクトのコンストラクタ”が出力される。
これは、”Cat.prototype = new Pet();”のタイミングで基底オブジェクトのコンストラクタが実行されてしまう為である。
これを回避する為には、以下のように継承部分を変更する必要がある。

まず、ダミーのオブジェクト”Func”を定義する。
次に”Func”のプロトタイプに基底オブジェクトのプロトタイプを設定する。
さらに新しいオブジェクト”Cat”のプロトタイプに”Func”から生成したインスタンス(つまり基底オブジェクトのプロトタイプ)を設定する。
最後に新しいオブジェクト”Cat”のプロトタイプに自身のコンストラクタを設定する。
これで継承時に基底オブジェクトのコンストラクタが実行されることがなくなる。

 

Object.createを利用して継承

上記の継承をECMAScript5で定義されたObject.createを利用すると以下のように表すことができる。(新しいオブジェクト”Cat”のほかに別のオブジェクト”Dog”も追加している)

Object.createの第一引数に基底オブジェクトのプロトタイプを、第二引数に新しいオブジェクト自身のコンストラクタを指定して生成したオブジェクトを新しいオブジェクトのプロトタイプに設定している。(メソッドなどを追加する場合も第二引数に列挙する)
Object.createでオブジェクトを生成する際には、コンストラクタは実行されないので継承時に基底オブジェクトのコンストラクタが実行されることはない。

 

おすすめ

1件の返信

  1. a より:

    TypeScriptはC#風に書ける。privateやpublicなどを使いC#風に書いてみる。ビルドが通る。ほとんどC#と一緒だ

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください