2012-12-19 20 views
5

L'unica domanda che ho è perché la seconda volta chiamo x.modifyPrivate (true) perché è quando viene eseguita la riga X, il valore di _private passato è ancora 'falso'.Membri privati ​​nel modello del modulo, non modificabili?

Posso dare un senso a questo se modifico leggermente la mia conoscenza delle chiusure per essere che la chiusura è fatta per riferimento, e quando cambi il valore di un riferimento non stai cambiando il valore al quale il riferimento originale ha puntato, tu stanno cambiando il riferimento stesso per indicare un nuovo valore ... Ma tutta questa cosa è molto confusa e sono sicuro che qualcuno là fuori può indicarmi un diagramma sulla rete che lo spiega.

Sono anche molto interessato a sapere come scrivere questo codice in modo che _private sia in effetti modificato per le successive chiamate a modify().

+4

Gli argomenti sono passati per valore in JS. Ciò significa che la funzione 'modify' è efficacemente priva di significato. Anche se 'val' si riferiva ad un oggetto, il valore della sua _local_ copy (= reference pure) verrebbe riscritto, non l'oggetto stesso. – raina77ow

+0

Sì, grazie, non posso credere di averlo dimenticato. Le chiusure usano il riferimento, le chiamate di funzione usano il valore. Destra! – JayPrime2012

risposta

3

JavaScript passa sempre in base al valore, quindi non è possibile passare una variabile a una funzione e assegnare alla funzione un nuovo valore come si è tentato di fare.

La funzione modify non è affatto necessaria. Basta fare questo:

constructorFunc = function() { 
    var _private = false; 

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

Il metodo modifyPrivate ha accesso al privato _private, da quando è stato definito in un ambito interno. Restituisce this come suggerito da raina77ow, quindi puoi concatenare un'altra chiamata al metodo x se lo desideri (ad esempio x.modifyPrivate(true).foo(), se definisci foo come hai fatto per modifyPrivate).


Ora, se si ha realmente bisogno di modificare il valore da una funzione esterna che non ha accesso a tale ambito, è possibile avvolgervi valore privato in un oggetto, e passare l'oggetto. In questo caso, il valore passato sarà un riferimento all'oggetto, in modo da modificare le sue proprietà avrebbe funzionato (notare che non è possibile riassegnare l'oggetto, basta manipolare le proprietà):

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

Preferirei restituire "questo" in setter.) – raina77ow

+0

ha senso; restituire 'toVal' era un'ipotesi, non sono sicuro di ciò che l'OP vuole restituire (il codice originale restituito' undefined'). – bfavaretto

+0

Grazie, ti prendo. In realtà la funzione di modifica è un "set o get" a seconda che ci sia o meno un valore, e se il valore è cambiato aggiorna il mio database e memorizza anche i valori nella cache in modo che non recuperi sempre dal database. Dovrò fare questa domanda in un modo "come posso evitare di inserire il mio 'setOrGetMethod' incapsulato qui come funzione 'modifica' come suggerisce bfavaretto? Causare inline quella logica in un metodo anonimo solo per ottenere su private non sembra necessario. pensa ad un modo ... Dovrei avvolgere tutti i miei _private vars in un oggetto e passare l'oggetto? – JayPrime2012

Problemi correlati