5
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 的值仍然是“假”。

如果我稍微修改一下我对闭包的了解,使我可以理解这一点,即闭包是通过引用完成的,并且当您更改引用的值时,您并没有更改原始引用指向的值,而是更改了引用本身指向一些新的价值......但这整件事非常令人困惑,我相信那里的人可以向我指出网上的一张图表来解释这一点。

我也很想知道如何编写此代码,以便实际上修改 _private 以供后续调用 modify()。

4

1 回答 1

3

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

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

constructorFunc = function () {
    var _private = false;

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

该方法modifyPrivate可以访问 private _private,因为它是在内部范围中定义的。它this按照raina77ow 的建议返回,因此您可以根据需要链接另一个方法调用x(例如x.modifyPrivate(true).foo(),如果您foo像为 所做的那样定义modifyPrivate)。


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

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); 
于 2012-12-19T15:49:34.040 回答