2016-02-17 19 views
5

Mi sto avvicinando all'apprendimento di JavaScript da uno sfondo di Ruby, quindi ho difficoltà a capire (e a metterlo in parole) perché il mio codice non riesce a produrre i risultati bisogno. Ho eseguito questo a pythontutor.com per vedere una procedura dettagliata di cosa sta succedendo, e conferma i miei sospetti. Tuttavia, non sono sicuro del perché questo sia il caso.Funzione Javascript e prototipo - problema di routing di base tramite metodi di chiamata

Sto costruendo un termostato e si suppone che restituisca 'verde' una volta che la temperatura è inferiore a 18dC. Sulla mia penultima riga, il console.log è 17, che è corretto, tuttavia quando chiamo thermostat.displayColor sull'ultima riga, si dice ancora giallo. Il codice termina lì e non torna indietro attraverso this.displayColor = this.currentColor() che mi aspetto (poiché lo ha eseguito alla prima esecuzione per definire il colore iniziale come 'giallo'.

Il codice funziona correttamente e restituisce 'verde' se cambio il codice per chiamare direttamente il metodo prototipo this.currentColor(), tuttavia voglio solo sapere perché non mi permette di farlo nel modo in cui ho scritto qui sotto.

Non sono sicuro della terminologia per descrivere questo problema, quindi scusate in anticipo per il mio titolo non accurato

var DEFAULT_TEMP = 20; 

function Thermostat(){ 
    this.temperature = DEFAULT_TEMP; 
    this.maxTemp = 25; 
    this.powerMode = 'on'; 
    this.displayColor = this.currentColor() 
}; 

Thermostat.prototype.downButton = function(){ 
    if (this.temperature === 10){ 
    throw new Error('temp cannot be lower than 10dC'); 
    }; 
    this.temperature --; 
}; 

Thermostat.prototype.currentColor = function() { 
    if ((this.temperature >= 18) && (this.temperature < 25)) { 
    return 'yellow' 
    } 
    else if (this.temperature < 18) { 
    return 'green' 
    } 

    else { 
    return 'red' 
    } 
}; 

var thermostat = new Thermostat(); 
for (var i = 1; i <= 3; i++) { 
     thermostat.downButton(); 
     }; 
console.log("spec file test green, temp should be 17 and is:" + thermostat.temperature) 
console.log(thermostat.displayColor); //this should be green, but it is yellow! 

risposta

3

È necessario chiamare il metodo currentColor(), displayColor è impostato solo nel costruttore (in cui la temperatura è 20) e non viene aggiornato quando la temperatura cambia.

Potrebbe avere senso per aggiungere l'impostazione di colore al metodo downButton:

Thermostat.prototype.downButton = function(){ 
    if (this.temperature === 10){ 
    throw new Error('temp cannot be lower than 10dC'); 
    }; 
    this.temperature --; 
    this.displayColor = this.currentColor(); 
}; 
+0

grazie Rob per la rapida risposta! C'è qualche ragione particolare per cui il displayColor viene impostato una sola volta (al momento dell'inizializzazione)? Mi piacerebbe leggere di più su questo, è probabilmente un concetto davvero fondamentale, ma non sono sicuro di come iniziare a cercare questo – ugotchi

+1

@ggwc ogni volta che crei l'istanza che stai chiamando la funzione di costruzione. Questa è l'unica volta in cui viene chiamata la funzione 'Termostato()' perciò 'displayColor()' viene chiamato solo una volta – Sean

+1

@ggwc Nessun problema. Forse stai pensando che 'this.displayColor = this.currentColor()' legherà il valore di 'displayColor' in qualche modo che chiama sempre la funzione' currentColor' per ottenere il suo valore, ma non è quello che succede. Il costruttore ('function Thermostat() {...') è chiamato una volta quando istanziate 'new Thermostat()' ei valori impostati all'interno del costruttore sono statici, a meno che non vengano aggiornati da altre funzioni membro o esternamente. –

2

Come dice Rob, è necessario chiamare la funzione che calcola il colore corrente. Ecco il suo suggerimento insieme ad alcuni miglioramenti al codice:

function Thermostat() { 
 
    this.MIN_TEMP = 10; 
 
    this.MAX_TEMP = 25; 
 
    this.temperature = 20; 
 
} 
 

 
Thermostat.prototype.decreaseTemp = function() { 
 
    if (this.temperature > this.MIN_TEMP) this.temperature--; 
 
}; 
 
Thermostat.prototype.increaseTemp = function() { 
 
    if (this.temperature < this.MAX_TEMP) this.temperature++; 
 
}; 
 
Thermostat.prototype.currentColor = function() { 
 
    if (this.temperature < 18) return 'green'; 
 
    if (this.temperature < 25) return 'yellow'; 
 
    return 'red'; 
 
}; 
 

 
var thermostat = new Thermostat(); 
 
for (var i = 1; i <= 3; i++) { 
 
    thermostat.decreaseTemp(); 
 
} 
 

 
// no errors mean all assertions pass 
 
thermostat.temperature.should.equal(17); 
 
thermostat.currentColor().should.equal('green');
<script src="https://cdnjs.cloudflare.com/ajax/libs/should.js/8.2.2/should.min.js"></script>