2

重複の可能性:
Javascript 外部スコープ変数アクセス

以下のようなJavaScriptモジュールがあります。私が抱えている主な問題は、プライベートから「this」スコープの変数にアクセスする方法ですsomeOtherFuncthis.myvarプライベートでアクセスする方法はありますかsomeOtherFunc

var mymodule = (function(){

    return {   
        MyObj : function() {

            this.myvar = 123;

            this.publicfunc = function() {
                someOtherFunc();
            };

            var someOtherFunc = function() {
                //this doesn't seem to work
                this.myvar = 456;
            };

        }
     }
}

アイデアは、次のようなことができるようになりたいということです

new mymodule.MyObj().publicfunc、しかしsomeOtherFunc非公開にする

4

6 に答える 6

2

私の以前の答えを忘れてください。これは、こののプライベート バージョンを追加するだけで実行できます。

var mymodule = (function() {
    return {   
        MyObj : function() {
            this.myvar = 123;
            var that = this;

            this.publicfunc = function() {
                someOtherFunc();
            };

            var someOtherFunc = function() {
                that.myvar = 456;
            };
            return this;
        }
    };
});

コードで MyObj を呼び出すたびに、新しい objectが取得されることに注意してください。
したがって、これはあなたが望むことを行います:

>var o = new mymodule().MyObj()
>o.myvar
123
>o.publicfunc()
>o.myvar
456

しかし、これではありません

>var m = new mymodule()
>m.MyObj().myvar
123
>m.MyObj().publicfunc()
>m.MyObj().myvar
123

それがあなたが望むものでない場合は、このようなことを検討してください

var mymodule = (function() {
    var myObj = null;
    this.MyObj = function() {
        if(myObj != null)
            return myObj;
        myObj = {};
        myObj.myvar = 123;

        myObj.publicfunc = function() {
            someOtherFunc();
        };

        var someOtherFunc = function() {
            myObj.myvar = 456;
        };
        return myObj;
    };
});
于 2012-11-27T17:32:20.803 に答える
1

あなたが探しているのは、myvar変更をカプセル化する方法だと思います。他のいくつかの回答が実行されると、最初に返されたオブジェクトがその初期値を保持するため、myvar通常はそのままになります。123mymodule

変更された後でも値を取得する関数を返すとmyvar、問題が解決すると思います。

これが私のために働くコードです:

var mymodule = (function(){
    var myvar = 123,
        publicfunc = function() { myvar = 456 },
        getMyVar = function() { return myvar; };

    return {
        someOtherFunc : publicfunc,
        myPublicVar : getMyVar
     };
}());

mymodule.someOtherFunc();
alert(mymodule.myPublicVar());​  //gives you 456

ここでJSFiddle 。

これが役立つことを願っています。

于 2012-11-27T17:52:18.893 に答える
1

もう少し意図的に構築してみませんか?

// this one returns an object used like:
// myModule.myInt; /* 456 */
// myModule.myFunc(); /* 124 */
var myModule = (function () {
    var secretData = 123,
        publicData = 456,

        publicFunc = function () { return privateFunc(secretData); },
        privateFunc = function (num) { return num + 1; },

        public_interface = {
            myInt  : publicData,
            myFunc : publicFunc
        };

    return public_interface;

}());

返されたパブリック オブジェクトに明示的に名前を付けるというトラブルを経験しましたが、何がパブリックで何がパブリックではないかが非常に明確になりましたが、これらのそれぞれは、1 つの例外を除いて、互いの変数バージョンにアクセスできます。myModule.myIntまたはを変更するpublicDataと、それらは等しくなくなります。


以下のコメントで私が何を意味するかを示すために、独自のプライベート データ/メソッドを使用して複数のインスタンスを作成し、関数スコープのレイヤーをもう 1 つ追加します。

var myModule = (function () {

    var static_int = 789,

        makeInstance = function (/* any constructor values */) {
            var secretData = 123,
                publicData = 456,

                publicFunc = function () { return privateFunc(secretData); },
                privateFunc = function (num) {
                    console.log(static_int);
                    return num + 1;
                },

                public_interface = {
                    myInt  : publicData,
                    myFunc : publicFunc
                };

            return public_interface;
        };

    return makeInstance;
}());

次のように使用します。

var newModule = myModule(/* instance parameters */);
newModule.myFunc();

...また

var num = myModule(/* instance parameters */).myFunc();

メモリを節約したい場合は、静的レイヤー内に静的ヘルパー関数を含めることができます。

var myModule = (function () {

    var static_int = 789,

        static_addOne = function (num) { return num + 1; },
        static_divideBy = function (dividend, divisor) { return dividend/divisor; },

        makeInstance = function (/* any constructor values */) {
            var secretData = 123,
                publicData = 456,

                publicFunc = function () { return privateFunc(secretData); },
                privateFunc = function (num) {
                    console.log(static_int);
                    return num + 1;
                },

                public_interface = {
                    myInt  : publicData,
                    myFunc : publicFunc
                };

            return public_interface;
        };

    return makeInstance;
}());

これで、一度しか書き込まれない (つまり、メモリを節約する) 「プライベート」関数ができましたが、どのインスタンスでもそれらの関数を使用できます。

キャッチは次のとおりです。
スコープとクロージャーの仕組みにより、静的関数はインスタンスの値にアクセスできません (内部の関数は静的関数にアクセスできますが、その逆はできません)。

そのため、静的ヘルパー関数には引数として渡された値が必要であり、数値または文字列を変更する場合は、その関数から値を返さなければなりません

// inside of a private method, in any instance
var privateString = "Bob",

    privateFunc = function () {
        var string = static_helper(privateString);
        privateString = string;
        //...
    };
于 2012-11-27T17:35:51.557 に答える
1

myvarキーワードを使用して宣言し、var非公開にしてから、 なしでアクセスしますthis.

function MyObj(){

        var myvar = 123;

        this.publicfunc = function() {
            someOtherFunc();
        };

        var someOtherFunc = function(){

            alert(myvar);

        };            
}


var o = new MyObj();
o.publicfunc();

パブリック アクセスが必要な場合はmyvar、パブリック ゲッター/セッターを作成します。

jsFiddle デモ </p>

于 2012-11-27T17:38:31.363 に答える
0

bindメソッドを使用します。

var someOtherFunc = function() {
     this.myvar = 456;
}.bind(this);
于 2012-11-27T17:32:42.450 に答える
0

returnから何もしませんMyObj

return this;

それを修正する必要があります。

于 2012-11-27T17:32:28.000 に答える