2013年11月10日日曜日

連載:ちょっとディープなXPages 第2-7回~JavaScriptをもっと知ろう

みなさん!XPages開発していますか!?

今回は、JavaScriptのコンストラクタ関数と強制newパターンを説明しましょう。

コンストラクタ関数

JavaScriptには、Javaなどのクラスの概念はありません。でもnewでオブジェクトを作成したり、ArrayだとかDateだとかはクラスの概念で語られることが多いですよね。それらは正確にはクラスではなくコンストラクタ関数と呼ばれるものです。

コンストラクタ関数は、ArrayやDateなどビルドインのものもありますが、自作することもできます。その記述は下記のように行います。

var User = function(name){
    this.name = name; //プロパティ
    this.sayHello = function(){
        return this.name + 'さん、こんにちは!';
    } //メソッド
}

//オブジェクト作成
var kenji = new User('Kenji');
print(kenji.name); // 'Kenji'
print(kenji.sayHello()); // Kenjiさん、こんにちは!

コンストラクタ関数の内部では、thisは新しいオブジェクトであり、それにプロパティやメソッド(関数)を追加していくように記述します。

お気づきかと思いますが、通常のメソッドと同じ記述ですよね。そのとおりで定義にコンストラクタ関数である特別な記述はありません。呼び出し方で、その関数が通常の関数として動作するかコンストラクタ関数として動作するかが決まります。

newをつけて関数を呼び出したときは、内部では下記にような動作をします。

  • 新しい空のオブジェクトをthisして定義する
  • 関数の最後にthisを関数の戻り値とする

newを使わない場合、下記と同等となります。

var User = function(name){
    var newObject = {};
    newObject.name = name; //プロパティ
    newObject.sayHello = function(){
        return this.name + 'さん、こんにちは!';
    } //メソッド
    return newObject;
}

//オブジェクト作成
var kenji = User('Kenji');
print(kenji.name); // 'Kenji'
print(kenji.sayHello()); // Kenjiさん、こんにちは!

強制newコンストラクタ関数パターン

コンストラクタ関数である特別な記述がないということは、newを付けなくても呼び出せてしまいます。その場合、thisは呼び出し元でのthisとなってしまいますので、意図しない動作になってしまいます。

そこで、コンストラクタ関数では初めにthisが自信のコンストラクタ関数で生成されたものかを確認すことで、より安全に呼び出すことができます。

var User = function(name){
    if(!(this instanceof User)){
        return new User(name);
    }
    this.name = name; //プロパティ
    this.sayHello = function(){
        return this.name + 'さん、こんにちは!';
    } //メソッド
}

//オブジェクト作成
var kenji = new User('Kenji');
print(kenji.name); // 'Kenji'
print(kenji.sayHello()); // Kenjiさん、こんにちは!
var aiko = User('Aiko');
print(kenji.name); // 'Aiko'
print(kenji.sayHello()); // Aikoさん、こんにちは!

コンストラクタ関数の更なる改善

上記で紹介したコンストラクタ関数ではその中で定義している関数(例でのsayHello)は、newで呼び出されるたびに生成されています。これは、内容が変わらない静的なメソッドなので、これでは非効率です。prototypeを利用することで、効率的な実装できます。

また、ここでのnameやsayHelloはパブリックなメンバーになりますが、プライベートなものを作るには、クロージャを利用することで実現できます

これらについても、今後解説していきます。

海老原 賢次(EBIHARA Kenji)

リコーITソリューションズ株式会社(RICOH IT SOLUTIONS CO.,LTD.)

鹿児島ソリューション部(Kagoshima Department)

 

0 件のコメント:

コメントを投稿