Trying to understand getters, setters, constructor and this keyword

Tell us what’s happening:
I’m not fully understanding what is happening in this challenge’s solution code and wanted to get an explanation line by line. I’ll try to explain what I’m understanding… (I got it to pass but heavily relied on peeping the solution, as my lack of understanding will probably show)

  **Your code so far**

// Only change code below this line
class Thermostat {
constructor(fahr) {
  this.fahr = fahr;
}
get temperature() {
  return (5 / 9) * (this.fahr - 32);
}
set temperature(celsius) {
  this.fahr = (celsius * 9 / 5) + 32;
}
}
// Only change code above this line

const thermos = new Thermostat(76); // Setting in Fahrenheit scale
let temp = thermos.temperature; // 24.44 in Celsius
thermos.temperature = 26;
temp = thermos.temperature; // 26 in Celsius

so starting with the line

const thermos = new Thermostat(76); // Setting in Fahrenheit scale

this declares a variable thermos that includes an object (or is thermos the object?) instantiated by the new keyword, and the object contains one property with a value: {fahr: 76} (I don’t know if any of this is right)

Then comes:

let temp = thermos.temperature;

this declares a variable temp which equals value of the thermos object’s property temperature

But I don’t think thermos.temperature has been defined/declared yet, so does this ‘call’ the get portion of code so that it can determine the value of temperature based on the value of the thermos.fahr property?

Also does the this keyword in this.fahr just reference the fahr property of any objects with the class Thermostat?

And then I’m not even sure what the purpose of the next 2 lines is:

thermos.temperature = 26;
temp = thermos.temperature;

This just seems like it’s changing the value of the temp variable, thus changing the corresponding value of the thermos.temperature property

I’m blindly guessing that by changing this value, either the get or set portion of code would then update the corresponding thermos.fahr property’s value to whatever 26 celsius is in fahrenheit?

Sorry that was long winded but I’ve been on this challenge all day and my brain is now oatmeal

  **Your browser information:**

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36

Challenge: Use getters and setters to Control Access to an Object

Link to the challenge:

It is a method (a getter) of the Thermostat class so it exists on the object you created. Same with the setter.

In this scenario (using classes) this refers to the object that is accessing that property. Since you created the object thermos then this is pointing to thermos for this particular instance and thus you could think of it as thermos.fahr. In fact you could directly access this property using thermos.fahr in your code. But when you are defining the class you can’t use the name of a specific object in the class definition because they haven’t been created yet, you don’t know the names they will have, and there may be more than one of them. So this sort of becomes a placeholder for the object(s) which will be created for the class.

thermos.temperature = 26;

This is the setter. It executes the code inside of the setter. What is that code doing?

temp = thermos.temperature;

This is using the getter to set the value of temp. It executes the code inside of the getter. What is that code doing. One thing it is not doing is changing the value of anything. After executing these two statements what will the value of temp and thermos.fahr be?

I don’t think you need to blindly guess here. Which one (the getter or setter) has code that updates the fahr property in the class. They don’t call them “getter” and “setter” for nothing. One of those ought to be a tip-off :slight_smile:

2 Likes

Oh bb, that explanation was smooth. Thank you for explaining it, I think I’m almost there with understanding this lesson.

So the setter set temperature(celsius) creates the property this.temperature or thermos.temperature after the thermos object is instantiated

This makes it so that any value thermos.temperature is set to, like 26 in this example, this value becomes the celsius argument passed into the setter function (which in turn updates the thermos.fahr property’s value to the corresponding fahrenheit value)

The variable temp on the other hand uses the getter to determine/get thermos.temperature - which converts the thermos.fahr value into celsius

One thing I’m not understanding is that when I console.log(thermos); all that is returned is { fahr: 78.8 }

I’m confused why it does also return { temperature: 26 } - I’m guessing the property thermos.temperature is like a pseudo property only used in the getter/setter functions? I would have thought that the object thermos would have 2 properties created, fahr and temperature with the fahrenheit and celsius values respectively?

The getter and setter are on the prototype.

get-set-prototype

1 Like

They are in this case, but don’t make the same mistake i did: get and set are not specific to classes, but to objects. Any object can have getters and setters.

Within a class declaration, all functions contained by that class are defined on the prototype by default. There is an exception to that, but it’s a rabbit hole. So it doesn’t matter if it’s a getter, a setter, or a plain old function, they’re treated the same way. The class defines a constructor function and its prototype, and that prototype is simply an object.

But any object can have getters and setters, not just classes and not just prototypes.

When i followed our curriculum, i thought i could only use getters and setters in a class. Blew me away when i found out i was wrong.

Sure, methods in classes are by default on the prototype (which makes sense).

My post was just in response to the console.log question. The challenge output won’t show the getter and setter if you log the object.

class Thermostat {
  constructor(fahr) {
    this.fahr = fahr;
  }
  get temperature() {
    return (5 / 9) * (this.fahr - 32);
  }
  set temperature(celsius) {
    this.fahr = (celsius * 9 / 5) + 32;
  }
}
// Only change code above this line

const thermos = new Thermostat(76);
console.log(thermos)
// { fahr: 76 }

If you use a plain object the challenge output will show them, well sort of (code from the MDN article).

var o = {
  a: 7,
  get b() {
    return this.a + 1;
  },
  set c(x) {
    this.a = x / 2;
  }
};

console.log(o);
// { a: 7, b: [Getter], c: [Setter] }

I think they are from 2009 or something like that. If you look at the Browser compatibility on MDN you can also tell they are really old. I have never really used them much, but I think that is because I usually do not use OOP (or rarely).

1 Like