SEEDS Creator's Blog

javascript でのクラスのつくり方

ごきげんよう。プログラマの 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]

[コード1]

これはAという名前のクラスを定義してます。インスタンスの生成は

[code] var a = new A('a'); [/code]

[コード2]

とします。関係をまとめた図はこちらです。

figure1

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]

[コード3]

BAを継承してインスタンスメソッドtestをオーバーライドして(るようにふるまって)ます。関係をまとめた図は

figure2

コンストラクタで実行されている`A.call`は`Function.prototype`のメソッドで第1引数にとったオブジェクトをthisに束縛してAを実行してます。これでコンストラクタを継承してます。もちろんいらなければこの処理を外すだけです。 A.prototypeのメソッドはObject.create()で生成したオブジェクトを束縛して継承してます。 B.prototype.constructor = B;sizeofのためのおまじないです。(ここでちょろっと言及してます。) 図をみてもらえば理解される方もいると思いますが、注意としてクラスメソッドやクラス変数、つまりコンストラクタのプロパティは__proto__で束縛していないので継承されません。

まとめ

以上 javascript でのクラス定義の方法です。ほかにもクラスっぽいものを定義する方法はあるみたいですが正直どれがいいかまだわかりません。それを見極める力がまだない…。まあ実装にこだわりだせばそれほどの柔軟性をもっているのが javascript の強みであり面倒臭さであるんではないかと思います。