feeds2012/02/27カテゴリー:JavaScriptJavaScriptにおけるクラス定義TweetJavaScriptは、プロトタイプベースのオブジェクト指向をサポートしています。クラスベースのオブジェクト指向言語に比べて記述は大きく異なりますが、JavaScriptでもクラスを利用することができます。目次クラス定義とコンストラクタインスタンスに定義するpublicプロパティprototypeによるpublicメソッドインスタンスに定義するpublicメソッドprototypeによるpublicプロパティprototypeの動的拡張hasOwnProperty()による判定privateプロパティ・privateメソッド特権メソッド(プリビレッジドメソッド)staticプロパティ・staticメソッドクラス定義とコンストラクタまず、簡単なクラス定義の例から見てみます。JavaScriptでは、クラス定義のための特別な構文はなく、functionで定義した関数がコンストラクタとなり、関数名がクラス名となります。下記の例では、無名関数内にFooという名前のクラスを定義していますが、new演算子によりインスタンスを生成できることが確認できます。出力:trueインスタンスに定義するpublicプロパティクラスのインスタンスにpublicプロパティを定義するには、コンストラクタ内でthisキーワードを使ってプロパティを定義します。コンストラクタ内でのthisは、クラスのインスタンス自身を表します。下記の例では、インスタンスのpublicプロパティに外部からアクセスできることが確認できます。出力:property_1prototypeによるpublicメソッドクラスのインスタンスにpublicメソッドを定義するには、クラスのprototypeオブジェクトにメソッドを定義します。prototypeは、クラスの基になるオブジェクトで、そのクラスから作られる全てのインスタンスで共有されます。prototypeのプロパティとして、関数オブジェクトを代入することにより、インスタンスにpublicメソッドを追加することができます。出力:method_1インスタンスに定義するpublicメソッドpublicメソッドは、プロパティと同じようにコンストラクタ内でthisキーワードを使用してインスタンス自身に定義することもできます。prototypeは前述したように全てのインスタンスで共有されるため、メモリ効率化の面ではprototypeに定義した方が有利です。出力:method_1prototypeによるpublicプロパティpublicプロパティは、前述したようにインスタンス自身に定義するだけでなく、prototypeに定義することもできます。インスタンスに定義したプロパティとprototypeに定義したプロパティには、振る舞いに違いがある点には注意が必要です。下記の例では、インスタンスとprototypeにそれぞれプロパティを定義し、値を書き換えた後でdeleteで消去していますが、結果が異なります。JavaScriptでは、プロパティが参照された際、まずインスタンス自身のプロパティを探し、見つからない場合にprototypeのプロパティを探します。prototypeのプロパティは読み取り専用で、代入やdeleteはインスタンスに対して行われます。この特性をよく理解した上で、例えば定数のような扱いのプロパティはprototypeに定義するなど、適宜使い分けると良いでしょう。出力:property_2prototypeの動的拡張prototypeは、動的に拡張することもできます。下記の例では、クラスをインスタンス化した後でprototypeにメソッドを追加していますが、メソッド追加前にインスタンス化されたdogからも追加したメソッドを利用できることが確認できます。出力:walkhasOwnProperty()による判定hasOwnProperty()を使うことで、インスタンスに定義されたプロパティかprototypeに定義されたプロパティかを判別することができます。下記の例でわかるように、プロパティがインスタンスに定義されている場合のみ、trueを返します。出力:falseprivateプロパティ・privateメソッドprivateプロパティを定義するには、コンストラクタ内で変数をvar宣言します。privateメソッドもコンストラクタ内でvar宣言した変数に関数オブジェクトを代入するか、コンストラクタ内でfunctionキーワードで定義します。これらのprivateメンバには、外部からはもちろん、prototypeに定義したpublicメソッドからもアクセスできません。privateメンバにアクセスできるのは、コンストラクタ内か後述する特権メソッドだけです。特権メソッド(プリビレッジドメソッド)コンストラクタ内でthisキーワードで定義されたpublicメソッドは、privateメンバにアクセスすることができます。このようなメソッドは、特権メソッド(プリビレッジドメソッド)と呼ばれます。property_1staticプロパティ・staticメソッドクラスにstaticプロパティやstaticメソッドを定義するには、クラスオブジェクトに対して直接プロパティやメソッドを追加します。これらのstaticプロパティ・staticメソッドは、インスタンス化することなく、クラスを通して直接アクセスできます。