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

时间:2012-12-19 15:45:10

标签: javascript closures

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

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

如果我稍微修改我的闭包知识,可以通过引用修改闭包,当你更改引用的值而不是原始引用指向的值时,我就可以理解这一点,你是改变引用本身以指向一些新的值...但是这整个事情非常令人困惑,我确信有人可以指出我在网上的图解释了这一点。

我也非常有兴趣知道如何编写这段代码,以便事实上修改_private以便后续调用modify()。

1 个答案:

答案 0 :(得分:3)

JavaScript总是按值传递,因此无法将变量传递给函数并让函数为您尝试分配新值。

实际上根本不需要modify功能。就这样做:

constructorFunc = function () {
    var _private = false;

    return {
        modifyPrivate: function(toVal) {
            _private = toVal;
            return this; 
        }
    };
}
var x = constructorFunc(); 
x.modifyPrivate(true); 

方法modifyPrivate可以访问私有_private,因为它是在内部范围中定义的。它正按照raina77ow的建议返回this,因此如果您愿意,可以链接x的另一个方法调用(例如x.modifyPrivate(true).foo(),如果您像foo那样定义modifyPrivate 1}})。


现在,如果您确实需要修改无权访问该范围的外部函数的值,则可以将私有值包装在对象中,然后传递该对象。在这种情况下,传递的值将是对象的引用,因此修改其属性将起作用(请注意,您无法重新分配给对象,只需操作属性):

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);