11

有没有办法让模块模式中的公共函数动态访问私有变量?test1 显示了我的意思是“动态访问”但使用公共变量

var x = (function(){
    var x=0, y=2, z=5;

    return {
        toast: 123,
        test1: function(arg){
            return this[arg];
        },
        test2: function(){
            // ??
        }
    };
}());

console.log(x.test1("toast")); // 123
console.log(x.test2("y")); // should return 2

我最终创建了一个私有变量(一个对象)来存储我的私有变量,这样我就可以像那样访问它们

 privateVarStore[privateVarName]

但是,还有其他解决方案吗?

4

2 回答 2

10

演示

是的。

很抱歉让 Adam Rackis 失望,但你可以用(邪恶的)eval 来做到这一点:

var x = (function(){
    var x=0, y=2, z=5;

    return {
        toast: 123,
        test1: function(arg){
            return this[arg];
        },
        test2: function(a){
            return eval(a)
        }
    };
}());

console.log(x.test1("toast")); // 123
console.log(x.test2("y")); // should return 2  -> does return 2

这是eval应该使用的少数例外之一。

编辑,根据 Hans B PUFAL 的建议(评论),您可以并且应该验证以下参数test2

test2: function(a){
    return /^[$_a-z][$_a-z0-9]*$/i.test (a) ? eval(a) : undefined;
}
于 2011-12-25T05:36:17.200 回答
7

(至少不是不诉诸eval,根据 qwertymk 的回答)。

y不是的属性(考虑将此对象命名为比避免与局部变量混淆x更好的名称)。 是一个局部变量,它的方法已经形成了一个闭包。 xxyx

的任何x方法都可以访问y,但不是通过说this.y,而是y直接访问。

同样,y它不是您的 object 的属性x。它只是创建的函数中的一个局部变量x,从而导致x' 方法在其上形成一个闭包。

因此,要test2返回y,只需执行以下操作:

test2: function(){
    return y;
}

要创建一个允许您访问私有变量的方法,请考虑以下内容:

var x = (function () {
    var privateMembers = { x: 0, y: 2, z: 5 };

    return {
        getPrivate: function (name) {
            return privateMembers[name];
        },
        toast: 123,
        test1: function (arg) {
             return this[arg];
        },
        test2: function () {
           // ??
        }
    };
})();

进而

alert(x.getPrivate("y")); //alerts 2

看看这个小提琴

于 2011-12-25T04:28:54.377 回答