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

私が持っている 1 つの質問は、なぜ x.modifyPrivate(true) を 2 回目に呼び出したのかということです。行 X が実行されたときに、渡された _private の値がまだ「false」であるのはなぜですか。

クロージャーに関する私の知識を少し変更して、クロージャーが参照によって行われるようにすると、これを理解できます。参照の値を変更すると、元の参照が指していた値を変更しているのではなく、参照を変更しています。それ自体が何らかの新しい価値を指し示している...しかし、これは全体的に非常に紛らわしいので、誰かがこれを説明するネット上の図を教えてくれると確信しています。

また、modify() へのその後の呼び出しで _private が実際に変更されるように、このコードを記述する方法を知ることにも非常に興味があります。

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()に定義する場合)。foomodifyPrivate


ここで、そのスコープにアクセスできない外部関数からの値を本当に変更する必要がある場合は、プライベート値をオブジェクトでラップして、オブジェクトを渡すことができます。この場合、渡された値はオブジェクトへの参照になるため、そのプロパティを変更すると機能します (オブジェクトに再割り当てすることはできず、プロパティを操作するだけであることに注意してください)。

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 に答える