新入社員JavaScript事始め(#3)「クラス定義の簡単な説明」

2016 年 10 月 12 日 by 山平

前回、前々回に引き続き、JavaScriptについて、簡単な説明を行いたいと思います。

今回も以後、「JS」と略記しますね。

JSの簡単な説明の最後はクラス定義です。
JSは一般的な「クラスベース」のオブジェクト指向ではなく「プロトタイプベース」という考え方です。
聞きなれない言葉だと思いますが、最初は深く考える必要はないと思います。

では以下にコードを示します。

JavaScript:
  1. (function(g){
  2. var local = 0; //①
  3. g.MMM = function(){ this.val = local; }; //②
  4. g.MMM.prototype.inc = function(){ return (this.val = ++local); }; //③
  5. })(this);

JSのクラス定義は大きく分けて3つに分かれています。
これに加えて、第一回で説明しなかった「(function(g){})(this)」もあるので4つとも言えますね。

①ローカル変数の定義
JSのオブジェクトとメソッドはすべてpublic扱いになります。
なので、普通に書くとカプセル化が全くできないことになってしまいますが、「クロージャ」という仕組みを使って、外部から変更できないprivateな値を保持します。
簡単に言うと、ローカルスコープで宣言した変数(関数も可)をクラス内で参照することで、外部から変更可能なクラスのメンバから外してしまえ、ということになります。

②コンストラクタの定義
変数に関数を代入しているように見えますが、その通りです。
JSはFunction定義をコンストラクタとしてクラスを定義します。
このg.MMMがクラス名になるので、「var c = new MMM();」と書くと、MMMクラスのインスタンスが生成できます。

③メソッドの定義
メソッドはプロトタイプに定義します。
プロトタイプベース感がありますね。
クラス定義した「MMM」のひな型が「MMM.prototype」で、インスタンスを生成する際に、プロトタイプが持っているメソッドがインスタンスに引き継がれます。
ちなみにインスタンスに後からメソッドを追加できますが、プロトタイプを書き換えたわけではないので、ほかのインスタンスに影響はありません。

このコードを実行すると、グローバル空間には「MMM」というクラス定義だけが追加されます。
ここでやっと「(function(g){})(this)」に入れるのですが、①のローカル変数をグローバル空間に宣言してしまうと、どこからでも参照できてしまうのでクロージャの意味がなくなってしまいます。
そこで、無名関数の中でクラス定義だけをグローバル空間に定義することで、ほかの余計な宣言でグローバル空間を汚さないようにしています。

駆け足ではありますが3回にわたってJSの特徴的な部分を簡単に説明しました。
JSを覚えてみたい方の足掛かりになれば幸いです。

タグ:

TrackBack