有没有办法让模块模式中的公共函数动态访问私有变量? 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]
但是有另一种解决方案吗?
答案 0 :(得分:9)
是强>
很抱歉让Adam Rackis失望,但你可以用(邪恶)评估来做到这一点:
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;
}
答案 1 :(得分:7)
否(根据qwertymk的回答,至少没有诉诸eval
)。
y
不是x
的属性(考虑将此对象命名为比x
更好的内容,以避免与局部变量x
混淆)。 y
是一个局部变量,x
的方法形成了一个闭包。
任何x
的方法都可以访问y
,但不能通过this.y
说,而是直接访问y
。
同样,y
不属于您的对象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