ES6: getters and setters

Here is the link to the topic:

There are a few questions I would like to ask

when are getters and setters called?
If i am not wrong setter is called when we would want to set the value in the object. similarly getter will run when we would want to print the value we want.

can we name getter and setter anything? if so then why error “getter and setter should be defined” displayed when i set the name to temp?
is it because a variable temp is already defined below, i.e.

let temp = thermos.temperature; // 24.44 in Celsius

why cant we do the calculations in getter like this:
let x = (5 / 9) * (this.fahrenheit - 32);
return x

how do we know if the temperature entered by user is in C or F. what if the temperature is already in C but when get is called the formula runs again. similarly what if its already in F but when setter runs the formula runs again.
wont the temperature become wrong then?

let temp = thermos.temperature; // 24.44 in Celsius

temp = thermos.temperature; // 26 in Celsius

why is a new variable let temp is used here.

if it is used to print value then we were to print using console.log command like:
console.log(thermos.temperature) would work fine??

class Book {
  constructor(author) {
    this._author = author;
  }
  // getter
  get writer() {
    return this._author;
  }
  // setter
  set writer(updatedAuthor) {
    this._author = updatedAuthor;
  }
}
const novel = new Book('anonymous');
console.log(novel.writer);  // anonymous
novel.writer = 'newAuthor';
console.log(novel.writer); 

here we can see
console.log(novel.writer);
is used to print author name. but the object does not have a property named writer.
similrarly with this
novel.writer = 'newAuthor';

please correct me on things that i mentioned if i was wrong.
Thanks

That’s part of the constraint of the class.
The constructor uses Farenheit, however both setter and getter use Celsius.
Meaning the “saved” temp will always be in F - neither getter nor setter change that.
If the user would create the class with Celsius, that’s like creating the book-class with the name of the book instead of the author. The program is not designed to check that - the user just has to use the class correctly. Or the result will be wrong.

This calls the getter method - and that one is called “writer”.
Because the getter does only return a value without having any inputs, it’s basically like an attribute. The get writer is more like a information for JS of how to treat that call. Getter and Setter are there to protect the values from outside influences.
However given Getters are still there to return values, by telling JS it’s a getter, it knows to treat it like an attribute for an outside call.

Don’t let getters and setters throw you. They are syntactic shortcuts. They do one thing: allow a slightly more convenient way to get or set the value of a property in a class/object. That’s it. They are not required. You could never use them and you would be able to write perfectly fine JS. But since they exist and a lot of people do use them, you will most likely run into them down the road and thus need to know about them.

Two of the most common methods people write when using classes/objects are “getters” to retrieve the value of a property and “setters” to set/change the value of a property. So you will often see a bunch of methods with names like getTemp() and setTemp() in order to get the value of the property temp and set the value of temp. I guess people thought this was ugly or maybe they thought typing out getTemp took too much time :slight_smile: Regardless, using getters and setters in JS allows you to forgo the traditional function-like syntax and instead use the fancy dot syntax to get/set the property value.

Traditional:

getTemp() {
  return this.temp;
}

To get the value of temp you would need to call this method as you normally would any other method (assume myTemp is an instance of the class):

console.log(`The current temp is ${myTemp.getTemp()}`);

Do you see how ugly that is, having to use parens to call a method to get the value of temp!!! Outrageous.

Instead, if we define a getter for temp we can do away with all of this nonsense.

get temp() {
   return this.temp;
}

Now we can write our console.log the way Nature intended it to be:

console.log(`The current temp is ${myTemp.temp}`);

Can you see how much better this is? I mean, I don’t know how I lived without this for so many years.

And setters are even better, because we can use the equals sign!

Traditional:

setTemp(t) {
  this.temp = t;
}

To set the temp you would have to do:

myTemp.setTemp(50);

My fingers are aching after having to type so many characters. Instead, if we define a setter:

set temp(t) {
  this.temp = t;
}

Now I can avoid carpal tunnel by doing:

myTemp.temp = 50;

OK, I am being very silly here. I’m just trying to make the point that there is no magic with setters/getters, they just allow you to do some very basic things that everybody needs to do with a slightly different syntax. Whether you think that syntax is actually better is a personal opinion (there are those who think that the getter/setter syntax is actually more confusing).

4 Likes

I would be hesitant to use the word “protect” here. If a property is public then it can be examined or modified outside of the class. This is why private class fields are now a thing. Until we had private fields we had to rely on people to respect the prefixed underscore notation that identified a property as private. But it really wasn’t. Getters and setters didn’t change that.

Now we can make fields actually private and we can use getters and setters to modify those fields. But it’s not the getter/setter that is protecting the field, it’s the #.

1 Like

Ah yeah, totally right - I meant in combination with private/protected prefixes. Ofcourse they alone won’t do anything like that.

The very sentence:

In the class, create a getter to obtain the temperature in Celsius and a setter to set the temperature in Celsius.

This is misleading the students/people.
Assumptions you have to make here:

  1. you will always return the temperature value through getter in Celsius.
  2. You will always call the setter passing a Celsius value which has to be stored in Fahrenheit.

These are not assumptions, they are definitions of how the getter/setter works. You are being told to implement them in a specific way, just like previous challenges have told you to implement functions in a specific way. So yes, you will always get a temp in C from the getter because that is the specific definition of the getter you have been given to implement. And yes, you will always pass the setter a value in C because that is the specific definition of the setter you have been given to implement.

The only assumption you are making here is that internally the class has to store the temp as F. I don’t think it says this anywhere in the instructions. You are free to decide whether you want to store it internally as C or F.

1 Like

Hey, Thanks for replying.
So when I do something like this:

class Thermostat {
  constructor(userInput) {
    this._temp = userInput
  }
  get temperature() {
    return 5/9 * (this._temp - 32)
  }
  set temperature(updatedValue) {
    this._temp = updatedValue
  }
}

I am setting the value as it is passed. But one of the test cases fail:
Screenshot from 2021-03-30 23-32-52

But if I set the value in F:

set temperature(updatedValue) {
    this._temp = updatedValue * 9.0 / 5 + 32
  }

It would pass the above mentioned Test Case.
Now These statement here:
Screenshot from 2021-03-30 23-38-20 Screenshot from 2021-03-30 23-32-52

They don’t seem to intstruct to set the temperature in F.
I agree with your points though but here’s what caught me. Sorry if I am being too pricky about the problem statements.

Because the setter takes a value in C, not F.

The internal temperature you are keeping in the class (using this._temp) is hidden from the specs. You get to decide whether you want to store this value as F or C. But your setter and getter must make the necessary conversions as needed since they only deal in C.

It might become more clear if you changed the name of the internal variable you are using to store the temp to something like this.tempF to remind you that you are storing it internally as F.

2 Likes

These two don’t work together. You get to select the internal temperature scale, but the getter and setter need to use C. You are mixing and matching internal representation and getter/setter logic here.

1 Like

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (’).

1 Like

Okay… I get it now!!!
I can store it in any unit , but the getter and the setter should work as per the specs.
I am just repeating whatever you said!! Makes sense now thank you!!