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

上面的示例返回两个闭包,既是函数,又是increment对构造函数中定义的变量get的引用。count

无法从外部访问,与之交互的唯一count方法是通过两个“封闭”功能。

请记住,闭包通过保持对其外部范围的引用来工作,因此以下内容不起作用

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

不会更改count内部的变量,Counter因为 foo.hack未在该范围内定义,相反,它将创建或覆盖全局变量count

于 2011-01-05T19:22:29.127 回答