2010年9月16日木曜日

クロージャによるプライベートなメンバ

最近JavaScript始めました(研究でWebGLをちょこちょこさわるので).


主にC/C++やC#でプログラミングするんだけど,アレらにはprivateだかpublicだかの制限が加えられる.例えばprivateだったらクラス内でしかアクセス出来ないとかね.でもJavaScriptにはそんな機能はないようだ.結構困る.

そこでクロージャなんかを使って変数を隠してしまうって方法がよく知られている(と思う).
関数型っぽくてトリッキー,それを使ってnewとかやってみる.
var Hoge = (function() {
    var private_number = 10;

    return function() {
        this.getNumber = function() {
            return private_number;
        }

        this.setNumber = function(n) {
            private_number = n;
        }
    }
})();

hoge1 = new Hoge();
hoge2 = new Hoge();
alert(hoge1.getNumber());
alert(hoge1.private_number);
hoge1.setNumber(20);
alert(hoge1.getNumber());
alert(hoge2.getNumber());
出力結果
10
undefined
20
20
関数Hogeの定義の流れとしては『関数を返す無名関数を実行して代入』していて,さらに返された関数のメンバ関数が『関数が定義された環境に束縛』されている.
どういうことかというと返された無名関数の外にprivate_numberというローカル変数が定義されており,返される無名関数に定義されているgetNumber, setNumberからそれを見ることができるってこと.
結果private_numberはC++でいう『private static int private_number』みたいな感じになる.

ちなみにnewを使わなかったら『private int private_number』みたいにstaticでないようにすることもできる.
var Hoge = function() {
    var private_number = 10;

    return {
        getNumber : function() {
            return private_number;
        },

        setNumber : function(n) {
            private_number = n;
        }
    };
};

hoge1 = Hoge();
hoge2 = Hoge();
alert(hoge1.getNumber());
alert(hoge1.private_number);
hoge1.setNumber(20);
alert(hoge1.getNumber());
alert(hoge2.getNumber());

出力結果
10
undefined
20
10

期待通りの結果獲得.でもこれで勝つる!といかないのが苦々しいところ.
その話はまた後日.

0 件のコメント:

コメントを投稿