JavaScriptでOO
JavaScriptは割とよくできたオブジェクト指向言語なのだが、クラスベースではなくプロトタイプベースなのでクラスベースの世界に慣れた人間にはちょっと理解し難いところもある。
でも、ちゃんと手続きを踏めばクラスを作ることは可能だし、継承もほんのちょっとの手間で実現できる。
正直、ここまで違うものに"Java"って名前をつけちゃったセンスは謎だけど。
以下覚え書き。
JavaScriptでクラスFooを定義するには、次のようにしてコンストラクタ函数を定義する。
function Foo(){
this.member = 初期値
}
ここでmemberはようするにメンバ変数だが、JavaScriptではプロパティと呼ばれる。
クラスFooのインスタンスfooを生成するには、次のようにキーワードnewをつけてコンストラクタFoo()を呼び出す。
foo = new Foo()
JavaScriptは型のゆるい言語なので、プロパティには函数だって代入できる。またfunctionで定義される函数は無名でもかまわないので、
function Foo(){
this.method = function()
// do something
}
とすることでメソッドを定義できる。できるのだが、newキーワードは要するにコンストラクタ函数で定義されるオブジェクトをインスタンス化するものなので、このやり方ではクラスでメソッドを共有されない(らしい)。
そこで、JavaScriptではプロパティを検索するときにprototypeというプロパティも参照するようになっている。prototypeはあらゆるオブジェクトに存在するプロパティで、これに登録されたプロパティは親オブジェクトのプロトタイプと同様に扱われる。
従って、メソッド定義は次のようになる。
Foo.prototype.method = function(){
// do something
}
このprototypeプロパティを適切に操作することにより、継承が表現できる。クラスBarがクラスFooを継承するとき、
Bar.prototype = new Foo()
これだけでFoo.prototypeに定義されているメソッドが引き継がれる。JavaScriptのように型のゆるい言語では継承とは実装の継承に他ならないから、これで継承が実現できたことになる。なんとも気持ちの悪い書き方ではあるが...
なお、上記の記法からわかるように、JavaScriptで実現できる継承は単純継承だ。もっとも、多重継承が必要なクラスをJavaScriptで書く羽目に陥ったとしたらそのプロジェクトはどこかが間違っているような気がする。
メソッドにデフォルト引数を設けたかったら、引数が値undefinedを持っているかチェックすればよい。JavaScriptでは函数呼び出しの際に引数の数はチェックされず、足りない引数にはundefinedが代入される。
投稿者 shig : 2005年11月17日 01:30
| トラックバック