2

これは可能ですか?

javascript でプライベート メンバーをエミュレートする方法を知っています。

var Class = (function() {
    var _private;

    Class = function() {
        _private = {};
    };

    Class.prototype.set = function(name, value) {
        _private[name] = value;
    };

    Class.prototype.get = function(name) {
        return _private[name];
    };

    return Class;

})();

このパターンの副作用は、2 つのインスタンスを作成するときです。

var instanceOne = new Class();
var instanceTwo = new Class();

次に、プライベート プロパティは次の間で共有されます。

instanceOne.set('test', 'me');
instanceTwo.get('test');

この問題の回避策はありますか?

よろしく

4

1 に答える 1

3

JavaScript で「プライベート」メンバーを作成する標準的な方法は、コンストラクター内でローカル変数を使用し、それらにアクセスする必要があるものはすべて、コンストラクターへの呼び出しのコンテキストでクロージャーとして定義することです。次のようにします。

function Class() {
    var privateValue = 0;

    this.getPrivateValue = function() {
        return privateValue;
    };
}
Class.prototype.doSomething = function() {
    // This function doesn't have access to `privateValue`
    // except through `getPrivateValue`, even though
    // it's accessible as a member of the instance
};

これは、おそらく最も有名なDouglas Crockfordによって説明されています。

これは、各インスタンスが関数の独自のコピーをClass取得するという影響があることに注意してください。これは、それぞれがコンストラクターへの異なる呼び出しに対するクロージャーであるためです (これが機能する理由です)。(ただし、これは関数のすべてのコードが複製されているという意味ではありません。少なくとも一部のエンジン (たとえば、Chrome などで使用されている Google の V8 エンジン) では、関連付けられた異なるコンテキストを持つ複数の関数オブジェクトで同じコードを共有できます。 .)getPrivateValue

(補足: この名前privateは予約語なので使用していません。ES3 では「将来の予約語」でした。ES5 では、strict モードでは 1 つだけです。詳細は.)

上記のオブジェクトではなく単純な変数を使用して、物事が実際よりも複雑に見えるのを避けました。あなたの例に適用する方法は次のとおりです。

function Class() {
    var privateData = {};

    this.get = function(name) {
        return privateData[name];
    };

    this.set = function(name, value) {
        privateData[name] = value;
    };
}

または、クラス全体のプライベート データをインスタンス間で共有したい場合は、次のようにします。

var Class = function() {
    var dataSharedAmongstInstances;

    function Class() {
        var privateDataForEachInstance = {};

        this.get = function(name) {
            return privateDataForEachInstance[name];
        };

        this.set = function(name, value) {
            privateDataForEachInstance[name] = value;
        };
    }

    return Class;
})();
于 2012-10-27T11:27:18.090 に答える