Javascript 模块模式中的私有成员,不可变?

Javascript 模块模式中的私有成员,不可变?,javascript,closures,Javascript,Closures,我的一个问题是为什么第二次调用x.modifyPrivate(true)为什么在运行x行时,传入的_private值仍然是“false” 如果我稍微修改我对闭包的了解,使闭包是通过引用完成的,并且当您更改引用的值时,您不是在更改原始引用所指向的值,而是在更改引用本身以指向某个新值,那么我可以理解这一点。。。但这整件事很让人困惑,我相信有人可以在网上给我指一张图表来解释这一点 我还非常有兴趣知道如何编写这段代码,以便在后续的modify()调用中修改_private JavaScript总是按值传

我的一个问题是为什么第二次调用x.modifyPrivate(true)为什么在运行x行时,传入的_private值仍然是“false”

如果我稍微修改我对闭包的了解,使闭包是通过引用完成的,并且当您更改引用的值时,您不是在更改原始引用所指向的值,而是在更改引用本身以指向某个新值,那么我可以理解这一点。。。但这整件事很让人困惑,我相信有人可以在网上给我指一张图表来解释这一点


我还非常有兴趣知道如何编写这段代码,以便在后续的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);