2015-08-27 20 views
6

Ho la seguente classeQualcuno può spiegare strani JavaScript con oggetti?

function Temp() { 
    var isHot=false; 
    return { 
    setHot: function(v) { isHot=v }, 
    getHot: function() { return isHot; }, 
    hot: isHot 
    } 
} 
var w = new Temp(); 
w.setHot(true); 

w.hot !== w.getHot() 

Perché vedo solo il valore modificato se accedo l'oggetto w tramite una funzione?

risposta

3
function Temp() { 
    return { 
    setHot: function(v) { this.hot=v }, 
    getHot: function() { return this.hot; }, 
    hot: false 
    } 
} 
var w = new Temp(); 
w.setHot(true); 

w.hot !== w.getHot() 

Questo, credo, s quello che avresti bisogno di fare per farlo funzionare. Non c'è affatto bisogno di isHot var. I metodi get set modificano direttamente il valore caldo degli oggetti, il che significa che getHot() e w.hot restituiranno il valore corretto.

Se si desidera rendere privato il valore isHot, quindi credo che sarà necessario utilizzare isHot var, ma non sarebbe necessario o fare riferimento al valore di w.hot. Non sono sicuro quali sarebbero le conseguenze di tale azione.

function Temp() { 
var isHot = false; 
    return { 
    setHot: function(v) { isHot=v }, 
    getHot: function() { return isHot; } 
    } 
} 
var w = new Temp(); 
w.setHot(true); 
w.getHot(); 

However you can not access w.isHot, essentially private var. 

Articoli correlati forse ..

+0

E se crei un'altra istanza di 'Temp', ti confonderai per giorni chiedendoti perché quando si imposta" setHot (true) "su un'istanza imposta' getHot() 'su' true' su tutte le istanze. Non esistono variabili di istanze private in JavaScript senza un pessimo hacker (come l'esempio di 'WeakMap' nel link che hai fornito). – Adam

+0

ha ha, si, questo è un ottimo punto! Sentiti libero di modificare il post per rendere quel punto più pertinente. – Emile

9

La proprietà "caldo" del vostro oggetto restituito è inizializzato quando viene creato l'oggetto, ma il suo valore è una copia del valore della "isHot". Le successive modifiche alla variabile locale (chiusura) "isHot" non influenzeranno la proprietà "hot"; non è semplicemente il modo in cui le variabili e le proprietà dell'oggetto funzionano.

JavaScript non fornisce un modo per rendere una variabile o una proprietà di oggetto un alias per un altro. Che cosa si può fare, tuttavia, è restituire un oggetto un po 'più elaborato:

function Temp() { 
    var isHot=false; 
    return { 
    setHot: function(v) { isHot=v }, 
    getHot: function() { return isHot; }, 
    get hot() { return isHot; } 
    } 
} 

che crea la proprietà "caldo" come funzione ES6 getter. Un riferimento alla proprietà "hot" ora fa sì che venga richiamata una piccola funzione, quindi la proprietà fornirà un modo per recuperare una copia del valore corrente di "isHot". (Questo non funzionerà negli ambienti JavaScript più vecchi.)

+0

Le risposte di solito sono esplicativi abbastanza, ancora don' t rendere l'immagine del tuo account meno disgustosa - Dracula sembra bello in contrasto con esso. – Vidul

+1

@Vidul ha ha - beh [il dipinto da cui è tratto] (https://www.oneonta.edu/faculty/farberas/arth/Images/ARTH_214images/van_eyck/arnolfini/painting.jpg) è molto bello, anche se il il soggetto è piuttosto strano. È nella National Gallery di Londra e consiglio vivamente una visita :) – Pointy

+0

Grazie per la raccomandazione :) Lo farò probabilmente. Il mio criterio è [l'espressionismo] (http://www.vangoghmuseum.nl/en) però. – Vidul

4

Perché hot è impostato per essere il valore di nel momento in cui viene eseguito Temp. Perché isHot è un primitive, il valore di w.hot è una copia di isHot e non un riferimento al valore corrente è isHot

Vale anche la pena sottolineare che questo è un modello terribile da usare se hai intenzione di creare più istanze di Temp perché isHot è una variabile locale per Temp e non una variabile istanza degli oggetti creati da new Temp()

var x1 = new Temp(); 
var x2 = new Temp(); 
x2.setHot(false); 
x1.setHot(true); 
x1.getHot() === true; //will return true 
1

Le risposte di cui sopra spiegano che si tratti di una copia della variabile di origine. Sarebbe un buon tono se si utilizzano funzioni impostate per ottenere o impostare il valore della variabile nella chiusura, preservando la isHot come una variabile privata solo ottenere /:

function Temp() { 
    var isHot=false; 
    return { 
    setHot: function(v) { isHot=v }, 
    getHot: function() { return isHot; } 
    } 
} 
var w = new Temp(); 
w.setHot(true); 

w.getHot(); // always returns the right value 
+1

Sono d'accordo con te @starikovs. Una volta imparato questo comportamento, non penso che esporrò più i primitivi. –

Problemi correlati