2010年11月17日

javascriptでクラスを作るの巻

ダンジョンスペシャルのプログラミングについて。気づいたことをちょこちょこ書きます。

今回はプレイヤーキャラクターを表すクラス、Memberクラスの作成について。
今までJavaでゲームをつくってきたんだけど、javascriptのクラス作成はJavaと様子が全然違っていた…
  
すべてが連想配列だ!

まずjavascriptの特徴として一番目についたのが、メンバー変数だろうがメソッドだろうが全部連想配列のキー・値のペアで表現されているということ。
例えばキャラクターの防御力を計算するメソッド、getDf()があるとするじゃないですか。

Javaだったら

public int getDf(){
  int df = this.equip[1].getValue() + this.equip[2].getValue() + this.equip[3].getValue();
  return df;
}

こんな感じになるんじゃない?equip[1]が盾、[2]が鎧、[3]が兜の前提でだよ?当然getValue()はそれぞれの装備の防御力を表している。うん、これは普通だ。だいたい普通のプログラミングはこうする。

ところがjavascriptは。

Member.prototype.getDf = function(){
  var df = this.equip.shield.value + this.equip.armor.value + this.equip.helm.vallue;
  return df;
}

さっきのJavaとだいたい同等のものを実装すると↑のようになる。まず意味が分からないのが Member.prototype.getDf この部分。
いきなりprototypeなんていう耳慣れないキーワードが出てくる上に、メンバー変数に普通に無名関数を代入しているように見える。いや、ように見えるんじゃなくて、javascriptのメソッドっていうのは連想配列のキーに無名関数を代入しているだけらしい。

プロトタイプ継承!

で、単なる連想配列の塊だと各インスタンスに関連性もクラスもへったくれもないので、一応継承のための仕組みとしてprototypeというキーワードがあるのだそうな。これがjavascriptの真骨頂、プロトタイプ継承だ!

javascriptのクラスは普通の連想配列だが、あらかじめprototypeというキーを持っている。newを使って新たなインスタンスを作成すると、クラス定義からprototypeに設定された値をコピってきてくれるんだそうな。何だそりゃ。言葉で書いても意味が分からないので、実際コードで書いてみる。さっきのgetDf()を使おうとすると

var member = new Member();
member.getDf();

おお。クラス定義の時とは全然様子が違って、Javaと1対1対応してるコードだ。ここでnew Member()によって作成されたインスタンスには、Member.prototype.getDf = で定義した無名関数がコピられてる。んで、javascriptのインスタンスってやつは、何も定義されていないメンバー変数やらキーにアクセスしようとすると、このprototypeに定義されているキーに同じ名前のものがないか探しに行くらしい。

member ←ここに「getDf」がない
member.prototype ←ここに「getDf」はあるかな・・・
という過程の後に、無事にgetDf()を見つけてきてくれるのだ。単なる連想配列しかないのにJavaっぽいことできるイカした奴め!

デメリット

ただ、プロトタイプ継承にも弱点があるらしく

var member = Member();

こんなふうにうっかりnewキーワードを抜かしてインスタンス生成を行おうとしても別に問題なく実行できる上に、定義したコンストラクタでグローバル名前空間を汚してしまう危険があるとのこと。

んまぁ、何言ってるのかさっぱりわからない問題点だし、俺一人で開発するぶんにはnewキーワードなんて忘れないようにすればいいだけなので気にしない。

どうしても気になるベストプラクティスマニアは↓のようなページを参考にするとよいよいよい

http://d.hatena.ne.jp/jdg/20090706/1246840565

むっちゃ参考になりそうなことが書いてある。俺もこれが理解できるようになるまで頑張ろう。
posted by LoyalTouch at 23:59| Comment(0) | TrackBack(0) | ダンジョンスペシャル | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのトラックバックURL
http://blog.seesaa.jp/tb/169756753

この記事へのトラックバック