ごきげんよう。プログラマの kinu です。javascript でのクラスのつくり方を調べました。クラスといっても前に書いた記事(http://www.seeds-std.co.jp/seedsblog/2157.html)のとおり javascript はプロトタイプベースなのでクラスは存在しません。ただクラスベースっぽくふるまうことはできるのでその方法をまとめました。この記事は先にあげた記事の情報をもとに書いてます。よければ先に読んでください
クラスっぽいものをつくる
以下がクラス定義のコードです。 [code] var A = (function () {
var classConst = 'const';
var A = function (name) { this.name = name; };
A.classVariable = 'class A'; A.classMethod = function () { return A.classValiable; }; A.prototype.instanceVariable = 'instance'; A.prototype.instanceMethod = function () { return this.instanceVariable+' '.this.name; }; A.prototype.test = function () { return 'hoge'; }; return A; })(); [/code]
これはA
という名前のクラスを定義してます。インスタンスの生成は
[code] var a = new A('a'); [/code]
とします。関係をまとめた図はこちらです。
http://www.seeds-std.co.jp/seedsblog/2157.htmlを先に読まれた方はお気づきの方も多いと思いますが、コンストラクタをつかってオブジェクトを生成してるだけです。ほとんど違いはありません。コンストラクタに追加したプロパティがクラスメソッド、クラス変数と同じ役割をして、プロトタイプに追加したプロパティがインスタンスメソッド、インスタンス変数と同じ役割を担います。違うのは、即時関数でコンストラクタの生成とプロトタイプの設定を包んでコンストラクタを返している点です。これは処理のスコープを限定するために使われてます。なのでこの中で変数を新たに定義してクラス内定数のように使うことができます。
継承のしかた
クラスベースの大きな特徴として継承というシステムがあります。javascript ではこのようにします。[コード1]がすでに定義されているとしてA
を継承したクラス`B`を定義するコードを例に示します。
[code] var B = (function () { var B = function (name) { A.call(this, name); }; B.prototype = Object.create(A.prototype); B.prototype.constructor = B;
B.prototype.test = function () { return 'huga'; }; return B; })(); [/code]
B
はA
を継承してインスタンスメソッドtest
をオーバーライドして(るようにふるまって)ます。関係をまとめた図は
コンストラクタで実行されている`A.call`は`Function.prototype`のメソッドで第1引数にとったオブジェクトをthis
に束縛してA
を実行してます。これでコンストラクタを継承してます。もちろんいらなければこの処理を外すだけです。
A.prototype
のメソッドはObject.create()
で生成したオブジェクトを束縛して継承してます。
B.prototype.constructor = B;
はsizeof
のためのおまじないです。(ここでちょろっと言及してます。)
図をみてもらえば理解される方もいると思いますが、注意としてクラスメソッドやクラス変数、つまりコンストラクタのプロパティは__proto__
で束縛していないので継承されません。
まとめ
以上 javascript でのクラス定義の方法です。ほかにもクラスっぽいものを定義する方法はあるみたいですが正直どれがいいかまだわかりません。それを見極める力がまだない…。まあ実装にこだわりだせばそれほどの柔軟性をもっているのが javascript の強みであり面倒臭さであるんではないかと思います。