Javascript 模块模式中的私有成员,不可变?
我的一个问题是为什么第二次调用x.modifyPrivate(true)为什么在运行x行时,传入的_private值仍然是“false” 如果我稍微修改我对闭包的了解,使闭包是通过引用完成的,并且当您更改引用的值时,您不是在更改原始引用所指向的值,而是在更改引用本身以指向某个新值,那么我可以理解这一点。。。但这整件事很让人困惑,我相信有人可以在网上给我指一张图表来解释这一点Javascript 模块模式中的私有成员,不可变?,javascript,closures,Javascript,Closures,我的一个问题是为什么第二次调用x.modifyPrivate(true)为什么在运行x行时,传入的_private值仍然是“false” 如果我稍微修改我对闭包的了解,使闭包是通过引用完成的,并且当您更改引用的值时,您不是在更改原始引用所指向的值,而是在更改引用本身以指向某个新值,那么我可以理解这一点。。。但这整件事很让人困惑,我相信有人可以在网上给我指一张图表来解释这一点 我还非常有兴趣知道如何编写这段代码,以便在后续的modify()调用中修改_private JavaScript总是按值传
我还非常有兴趣知道如何编写这段代码,以便在后续的modify()调用中修改_private JavaScript总是按值传递,因此无法将变量传递给函数,并让函数按照您尝试的方式为其分配新值 实际上根本不需要
modify
功能。只要这样做:
function modify(val, newVal) {
val = newVal;
}
constructorFunc = function () {
var _private = false;
return {
modifyPrivate: function(toVal) {
return modify(_private, toVal); // LINE REFERRED TO BELOW AS X
}
};
}
var x = constructorFunc();
x.modifyPrivate(true);
x.modifyPrivate(true); // _private still starts off as false, meaning it wasn't set to true
方法modifyPrivate
可以访问private\u private
,因为它是在内部作用域中定义的。它将返回raina77ow建议的this
,因此如果您愿意,可以链接另一个x
方法调用(例如x.modifyPrivate(true).foo()
,如果您像为modifyPrivate
定义foo
)
现在,如果您真的需要修改外部函数的值,而外部函数无权访问该范围,那么您可以将私有值包装到对象中,并传递该对象。在这种情况下,传递的值将是对对象的引用,因此修改其属性将起作用(请注意,您不能重新指定给对象,只需操作属性即可):
参数在JS中按值传递。这意味着您的
modify
函数实际上毫无意义。即使val
引用了一个对象,其本地副本(=引用)的值也会被重写,而不是对象本身。是的,谢谢,我不敢相信我忘记了。闭包使用引用,函数调用使用值。正确的!我更喜欢在setters中返回这个。)有道理;返回toVal
只是一个猜测,我不确定OP想要返回什么(原始代码返回未定义的
)。谢谢,我明白了。实际上,modify函数是一个“set或get”函数,具体取决于是否存在值,如果值被更改,它将更新我的数据库,并且它还缓存值,因此它不总是从数据库中获取。我需要以一种简单的方式问这个问题“我如何避免像bfavaretto建议的那样将封装在这里的‘setOrGetMethod’内联为‘modify’函数?因为将该逻辑内联到一个匿名方法中只是为了获取_private似乎是不必要的。我能想出一个办法。。。我必须把我所有的私人VAR都包在一个物体里,然后把这个物体传递出去?@Justinmooser先生:是的,那就行了。我会在答案中添加一个例子。好的,我只是想确认这是一种基本上通过引用传递的标准方法。显然,这里的modify()是对要设置的特定属性进行硬编码的,所以实际上我传入了一个“keyName”,所以我使用private[keyName],这样我就可以更改任何我想要的private。
constructorFunc = function () {
var _private = false;
return {
modifyPrivate: function(toVal) {
_private = toVal;
return this;
}
};
}
var x = constructorFunc();
x.modifyPrivate(true);
function modify(valObj, newVal) {
valObj.val = newVal;
// return whatever is apropriate
}
constructorFunc = function () {
var _private = {
val : false
};
return {
modifyPrivate: function(toVal) {
return modify(_private, toVal);
}
};
}
var x = constructorFunc();
x.modifyPrivate(true);