Jsにはクラスがないので正確ではないけど気にしない
Javascriptのクラスの宣言は主に
- var Hoge = function(){}
- function Hoge() {}
の2通りがある
http://qiita.com/VoQn/items/5df25f771d4602fd6293 によると、前者のやり方をしている場合、後述するObject.create()メソッドを使った継承を行うと
console.log(hogeChildObj); // hogeChildObjはHogeを継承したクラスのインスタンスが[object]としか出なくなりデバッグがしづらくなるらしい。
よってクラス宣言は後者のfunction型にしておく
参考ページ: https://gist.github.com/yoshimuraYuu/3301790
継承の際に気をつけるのは以下の2つ
- プロパティ
- メソッド
親のプロパティを子に引き継がせたい場合はParent.apply(this)を呼べばよい
function Parent() {
}
function Child() {
Parent.apply(this);
}こうすることで親のプロパティが子に引き継がれる。 引数が存在する場合でも以下のようにして簡単に引数を親クラスに渡すことができる
function Child() {
Parent.apply(this, arguments);
}次に、メソッドにあたるプロトタイプの宣言についてはよく以下の様な実装が用いられるが、 上に挙げたgistの参考ページにもあるようにいろいろと問題がある。
// これは微妙らしい
Child.prototype = new Parent();いちいちコンストラクタをnewするのも実装的に綺麗ではないし、あまりやりたくないところではある。
そこで、参考ページも出ていた、ECMAScript5から採用されているObject.create()メソッドを用いる https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/create
mozillaのページの方は少々わかりづらいが、オライリーの「Javascriptパターン」によると
function create(obj) {
function F(){}
F.prototype = obj;
return new F();
}のような実装がされているということなので、このパターンを用いるとプロトタイプの継承が以下のようにスッキリ書ける。
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;これでだいぶ綺麗にはなったが、さらにunderscore.jsのextendメソッドを使ってChildから定義するmethodもまとめる
var _ = require('underscore') // node.jsで起動する場合に記述する。ブラウザで実行する場合はこのソースの前にunderscore.jsを読み込んでおく
Child.prototype = _.extend(Parent.prototype, {
constructor: Child,
method1: function() { console.log("method1") }
});これでクラスの定義がだいぶすっきり書けるようになった。