Ruby の kind_of? の実装
前の記事でさりげなく登場していたこの行
if (!comd.kind_of(Command.Abstract))
について解説いたしましょう。
Ruby には kind_of? というメソッドがあり、オブジェクトが、任意のクラスまたはそのサブクラスのインスタンスかどうかを調べます。
"?" こそ付けられませんが JavaScript でも同様のことが可能で、ここでは comd が本当にコマンド・オブジェクトかどうかという妥当性チェックをしているわけです。
どうするかと言うと、isPrototypeOf というメソッドを使います:
Klass.prototype.isPrototypeOf(instance)
Klass.prototype が instance のプロトタイプ (言い換えると、クラス) かどうかを判断します。kind_of? とは逆方向ですが、同様のことが行えるわけです。*1
instance はサブクラスのインスタンスでも構いません: JavaScript における継承 = サブクラス化とは、以下の要領、即ち「サブ・プロトタイプ」への「スーパー・インスタンス」代入という手法を指すのですが、これによってサブクラスはスーパークラスと同じプロトタイプ・チェインに属することになるためです。
// Subklass、Klass は function オブジェクト Subklass.prototype = new Klass; // Subklass.prototype を拡張
余談ですが、この継承の方式から、JavaScript は Ruby と同様に単一継承の言語であると言うことができるでしょう。
それでは、kind_of? と同じ形になるように実装してみます。prototype.js の拡張に次のメソッドを追加します。
Class:
kind_of: function (object, klass) { return eval('klass.prototype.isPrototypeOf(object)'); }
Class.Methods
kind_of: function (klass) { return Class.kind_of(this, klass); }
以上です。
*1:"Klass.prototype" の部分はクラスのインスタンスを置いても良いらしいです: http://msdn.microsoft.com/library/en-us/script56/html/9c821319-c208-480f-915e-565ef6e017b6.asp