Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript function and prototype - basic routing issue through calling methods

I'm approaching learning JavaScript from a Ruby background, so I'm having some trouble understanding (and putting this into words) why my code is failing to produce the results I need. I ran this at pythontutor.com to see a step-by-step walkthrough of whats happening, and it confirms my suspicions. However, I'm not sure exactly why this is the case.

I'm building a thermostat, and its supposed to return 'green' once the temperature is below 18dC. On my penultimate line, the console.log is 17 which is correct, however when I call thermostat.displayColor on the last line it still says yellow. The code terminates there, and doesn't go back through this.displayColor = this.currentColor() which I expect it to (since it did this on the first run to define the starting color as 'yellow'.

The code works correctly and returns 'green' if I change the code to directly call the prototype method this.currentColor(), however I just want to know why it's not letting me do it in the way I've written below.

I'm not sure of the terminology to describe this problem, so apologies in advance for my title not being accurate.

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!
like image 582
ugotchi Avatar asked Feb 17 '16 21:02

ugotchi


2 Answers

You should call the currentColor() method, displayColor is only set in the constructor (at which time temperature is 20) and is not updated when the temperature changes.

It might make sense to add the color setting to the downButton method:

Thermostat.prototype.downButton = function(){
  if (this.temperature === 10){
    throw new Error('temp cannot be lower than 10dC');
  };
  this.temperature --;
  this.displayColor = this.currentColor();
};
like image 157
Rob M. Avatar answered Oct 16 '22 11:10

Rob M.


As Rob says, you should call the function that calculates the current color. Here is his suggestion along with some improvements to your code:

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>
like image 2
Tomalak Avatar answered Oct 16 '22 12:10

Tomalak