クロージャと Privileged メソッド
昨日の クロージャの続きです。
OOP な JavaScript では Public メソッド, Private メソッド, Privileged メソッド を定義できますが、クロージャを用いることにより Privileged メソッド が実現できます。
これらのメソッドについて順に見ていくことにします。
Public メソッド
まず Public メソッド を見てみます。オブジェクトのプロパティは、全てが Public で、これらはどんな関数からもアクセスすることができます。// 神様のコンストラクタオブジェクトにプロパティを追加するには、上記のように、
function God (name, feature) {
this.name = name;
this.feature = feature;
}
// 神様プロトタイプを上書き
God.prototype.getName = function(){
return this.name;
}
God.prototype.getFeature = function(){
return this.feature;
}
// 神様をインスタンス化して大黒天を生成
var god = new God('Daikokuten', 'Syokuji');
// Public メソッド呼出し
alert(god.getName());
///// Daikokuten
- コンストラクタで this キーワードにより追加する
- プロトタイププロパティで定義する
プロパティ及び Public メソッドはいつでも追加可能です。
例えば god オブジェクトに年齢プロパティと年齢を取得する Public メソッドを追加しようと思ったら、次のように実現できます。
// 年齢プロパティを追加
god.age = 2000;
// 年齢取得用 Public メソッドを追加
god.getAge = function (){alert(this.age)};
god.getAge();
/////2000
他の神様オブジェクトにも年齢プロパティと年齢を取得する Public メソッドを追加したい場合には、次のように God の prototype プロパティを上書きする方法を取ります。
// God の prototype プロパティを上書き
God.prototype.age = '';
God.prototype.getAge = function(){alert(this.age)};
// age プロパティに代入
god.age = 2000;
// Puclic メソッド呼出し
god.getAge();
/////2000
Private メソッド
次に Private メソッド を見てみます。// 神様のコンストラクタ上の例の場合、外部から関数内の var で定義された変数にアクセスすることができず、期待する値と異なる値が返ってくることが分かります。
function God (name, feature) {
/**
* 名前を表示する。
* var _getName = function(){....} と同じ
* @access private
*/
function _getName(){
alert(name);
}
// 渡された引数を保存
var name = name;
var feature = feature;
var self = this;
// 名前を表示する関数を実行
_getName();
}
// Public メソッドも定義する
function _getName(){ alert('uso')};
var god = new God('Daikokuten', 'Syokuji');
///// Daikokuten
// Private メソッドにはアクセスできない
_getName();
///// uso
また、name, age プロパティは定義されておらず、外部からアクセスできないことが分かります。
Privileged メソッド
作成時にしか名前を教えてもらえないのは不便なので、上記を改良して、3 回までなら神様の名前を教えてもらえる関数を作ってみます。この場合、name をプロパティとして定義せず、限定的に公開するメソッド (Privileged メソッド) を使って以下のように実現することができます。
// 神様のコンストラクタ上記のように Privileged メソッドは、クロージャを使い実現されます。
function God (name, feature) {
/**
* 制限回数以内かを返却する
* @access private
*/
function _getPrev() {
if (allowed > 0) {
allowed--;
return true;
}
return false;
}
// 渡された引数を保存
var name = name;
var feature = feature;
// 名前を教えることを許可する回数
var allowed = 3;
var self = this;
// Privileged メソッド
this.getName = function (){
return getPrev()? name: 'もう教えません。';
};
}
var god = new God('Daikokuten', 'Syokuji');
alert(god.getName());
///// Daikokuten
alert(god.getName());
///// Daikokuten;
alert(god.getName());
///// Daikokuten;
// 3 回目移行は教えてもらえない
alert(god.getName());
///// もう教えません。
まとめ
以上からPrivileged メソッドの特徴は次のようになります。- オブジェクト生成時に作成される
- プライベート変数とプライベートメソッドにアクセスできる
- パブリックメソッドなので、削除したり置き換えたりすることができる
- 改竄したり、隠蔽しているものを無理に明け渡させることはできない
