MENU

Loading...

【JavaScript】クラシカルにコードを継承するその1

コードを書くとき、既存のコードを再利用したいと言う場面が多々あるかと思います。その都度同じコードをペーストするのはナンセンスなので、今回は継承という方法でコードの再利用を実現する方法を書きます。

オライリーの「Javascriptパターン」を元に備忘録と理解の深化を兼ねて。また、ここでいう「クラシカル」とは「クラスのような」と言う意味で、伝統的な等の意味はありません。

準備

継承元となる親コンストラクタを作成します。

function Parent(name) {
  this.name = name || 'Adam';
}
Parent.prototype.say = function() {
  return this.name;
}

続いて子となるコンストラクタを作成し、これに親コンストラクタの内容が継承されるようにします。

function Child(name) {}

1.デフォルトパターン

最もよく使われるパターン。親コンストラクタのオブジェクトを子コンストラクタのプロトタイプに代入します。

function inherit(C, P) {
  C.prototype = new P();
}
inherit(Child, Parent);

メリット

  • 手軽に継承が実現できる。

デメリット

  • 固有のプロパティも継承されてしまう。
  • パラメータを子コンストラクタから親に渡せない。
var boy = new Child('Ken');
boy.say(); // 'Adam'

期待した結果を求めることができません。新しい子が必要になる度に継承を実行しなくてはいけません。

2.コンストラクタを拝借

デフォルトパターンの欠点を解決するパターン。

function Child(name) {
  Parent.apply(this, arguments);
}

applyメソッドを用いて、子オブジェクトに束縛されたthisを渡します。この場合、callメソッドを用いても同じ結果が得られます。親コンストラクタのプロパティを参照していたデフォルトパターンに対し、親コンストラクタを拝借しているこのパターンは、作成されたオブジェクト自身がプロパティを持っています。この時、thisに追加したプロパティのみが継承され、プロトタイプに追加したメンバは継承されません。

試しに上で作成したオブジェクトをnewしてsay()メソッドを呼び出してみると、undefined、つまり継承されていないことが確認できます。

var kid = new Child('Mike');
typeof kid.say; // undefined

メリット

  • 子から親に引数を渡すことができる。
  • 親を上書きしてしまう心配がない。

デメリット

  • プロトタイプに追加したメンバを継承できない。

その2に続く。