1

オブジェクトにコールバックを動的に割り当てようとしていますが、この関数にプライベート変数へのアクセスを許可しているときに、これを行う方法がわからないようです。壁にぶつかったところにコメントを付けて、関連するコードを以下にリストしました。

オブジェクトファクトリ

function makeObj ( o ) {
                function F() {}
                F.prototype = o;
                return new F();
            }

モジュール

var MODULE = (function(){
   var myMod = {},
       privateVar = "I'm private";
   return myMod;
})();

さまざまな試み


myMod.someDynamicFunc = function someDynamicFunc(){
    //privateVar === undefined;
    alert( privateVar );
}
myMod.someDynamicFunc();

myMod.prototype.someDynamicFunc = function someDynamicFunc(){
    //ERROR: Cannot set property 'someDynamicFunc' of undefined
    alert(privateVar);
}
myMod.someDynamicFunc();

この試みでは、モジュールオブジェクトにセッターを作成しようとしました...無駄になりました。

var MODULE = (function(){
       var myMod = {},
           privateVar = "I'm private";

           myMod.setDynamicFunction = function ( func ){
              if(func !== undefined && typeof func === "function"){
                //Uncaught TypeError: 
                //         Cannot read property 'dynamicFunction' of undefined
                myMod.prototype.dynamicFunction = func;
                //also tried myMod.dynamicFunction = func;
              }
           }
       return myMod;
    })();

var myModule = makeObject( MODULE );

myModule.setDynamicFunction(function(){
   alert(privateVar);
});

myModule.dynamicFunction();

JavaScriptを間違って使用していますか?オブジェクトが開始された後にコールバックを割り当てることができるようにしたいと思います。これは可能ですか?

4

2 に答える 2

2

動的に設定されたコールバック関数を介してプライベート変数にアクセスすることはできませんが (後でアタッチされた場合はクロージャーにならないため)、変数にアクセスできるシステムをセットアップすることはできます。

var MODULE = (function(){
   var myMod = {},
       privateVar = "I'm private";

   myMod.callback = function(fn) {fn(privateVar);};

   return myMod;
})();

var someDynamicFunc = function(param) {alert(param);};
myMod.callback(someDynamicFunc);

もちろん、誰でもこれを行うことができるため、これは実際にはプライベートではありません。他の誰かの動的にアタッチされた関数が同じ特権を持つことを許可せずに、動的にアタッチされた関数を介してアクセスする「プライベート」変数を持つことができる方法がまったくわかりません(したがって、実際にはプライベートではありません)。

于 2011-01-05T19:16:33.487 に答える
1

クロージャがどのように機能するかを正確に理解していなかったと思います。

クロージャとは、スコープが定義された外部スコープに常にアクセスできることを意味します。

function Counter(start) {
    var count = start;


    return {
        increment: function() { // has access to the outer scope
            count++;
        },

        get: function() {
            return count;
        }
    }
}

var foo = new Counter(4);
foo.increment();
foo.get(); // 5

上記の例では、関数とコンストラクターで定義された変数への参照の両方の2つのクロージャが返されます。incrementgetcount

外部からアクセスすることはできませんcount。外部からアクセスする唯一の方法は、2つの「閉じた」機能を使用することです。

クロージャは外部スコープへの参照を保持することで機能するため、以下は機能しないことを忘れないでください。

var foo = new Counter(4);
foo.hack = function() { // is not getting defined in the same scope that the original count was
    count = 1337;
};

これは、そのスコープで定義されていないため、 内部にある変数を変更しません。代わりに、グローバル変数を作成またはオーバーライドします。countCounterfoo.hackcount

于 2011-01-05T19:22:29.127 に答える