Why are getters and setters important?

Question

Why are getters and setters important?

Answer

Getters and setters are important to use when we want to perform some operation on data before we view or save said data. Getters and setters are also important to use when we want to make sure we don’t override data unintentionally, by making that data accessible only through our getters and setters

Hello,

So I’ve been struggling to understand why we would use getters and setters. In an exercise I came across a phrase that seems to finally maybe give me a clue that coincides with what you’re stating here.

“In the example above, we add getter methods for name and behavior . Notice, we also prepended our property names with underscores ( _name and _behavior ), which indicate these properties should not be accessed directly.”

Maybe I missed it, but I don’t remember that being specifically said. Are Getters and Setters used to return/set new values for properties that shouldn’t be directly changed or accessed? This seems to be in-line with what you’re saying above, and I think that makes sense.

Is this the main reason we use this?

Thanks,

3 Likes

Getters allow us to prepare the property output, over and above returning value alone. Setters allow us to validate and build some logic around the input, before setting the backing value.

12 Likes

So the purpose of an underscore is “privacy”, where you indicate to fellow coders not to access it directly, but using methods such as getters or setters. Was that explanation correct?

6 Likes

Pretty much nails it. Privacy on the Honor System.

9 Likes

i’M sorry to ask again on same question.
i still don’t understand clearly.
If we want some variable to set ‘privacy’ so that let other members to know that variable is not recommended for access/ then, why we create set and get for that variable. which helps us to get the variable and change it by getter and setter?

for me, it is very not efficient way.
if we can change or get the value however.
then it is better to not use underscore and create getter and setter isn’;t it?

2 Likes

We’re not looking for efficiency as much as maintainability and the Object Oriented Programming model. There is no such thing as ‘private’ in JS. Both the actual property (the one with the underscore) and the property that get creates are accessible.

OOP practices generally get and set variables (properties) using methods. That is the intent of getter and setter in JS objects and classes. This will begin to make more sense when you get into real world programming where a team is writing and maintaining a large code base. Unfortunately this is outside of my experience so I’ll not be able to furnish any real world example.

At any length, learn how to write and use getters and setters and the world is your oyster. They will become second nature in short order.

6 Likes

I see… so even though it looks not efficient.
when it comes to pair work or team work project it works so well for other fellows? i will keep it mind thank you! :grinning:

1 Like

@tera8793863138 @cosmic_noir @jnijnijni

While we can access a property by either its _propertyName or getters and setters,
The importance of getters and setters goes beyond alerting other coders of the privacy of a property, it can help you avoid errors which could make your code do things it shouldn’t, also to have a more readable and allows for easy debugging.
I’m going to try to establish why it is best to use getters and setters.
When we make a variable private, we only want to retrieve or modify the value following due process.

let’s use an analogy of cooking for setters:
let’s say you want to fry plantain, now literally speaking frying is the act of cooking in oil.
Do we just buy plantain and put it in the frying pan containing oil to fry it? NO!!!
Rather we have to follow due process:

  1. cut the plantain we want from the bunch.
  2. wash the plantain
  3. peel off the back
  4. cut the plantain to size.
  5. spice it up .
  6. fry

from the above we can see that while our end goal was to fry plantain , we would not achieve well fried plantain if we don’t follow due process

Now let’s come back to programming,

let person = {

_name: “Messi”,

_age: 33,

get name(){

return `The name of this person is ${this._name}.`

},

get age(){

return `${this._name} is ${this._age}years old.`

},

set age(newAge){

if (newAge > 0){

  this._age = newAge

}

else{

  console.log("You entered an invalid age,enter an age greater than 0")

}

}

}

console.log(person.age)

person.age = -19

lets assume our end goal is to change the age property of the person object above. We could easily just access the _age property above and reassign it. If we do that, the value changes, but we’ll be forgetting one crucial detail about age: that age can only be positive!
However if we try to reassign the age using our setter above, it first checks if the new age were passing meets our requirements and if it does it reassigns the _age property.
The example above is really simplified in a more complex program a value may need to meet many conditions before it is reassigned as the new value of a property and using setters will ensure that we follow due process before reassigning a property.

On the issue of getters, I feel it’s more about getting the value of a property in the way we want, for example we could store a the value of _temperature in kelvins (S.I unit), but in our getter we may choose to return the output in Celsius or Fahrenheit. Here _temperature can be viewed as a raw unit which if printed we wouldn’t understand. Then the getter returns the temperature in a format/unit we can easily understand.
We could also use this.temperature to get the _temperature within another method in the same object and perform different operations.

In the person object above, our getter for age returns an output that is formatted in an easily understandable way rather just the vague 33.
I hope I’ve been able to convince and not confuse you. :slightly_smiling_face:

17 Likes

My logic disagrees with yours in that I don’t believe a getter should return anything but the value itself, else how do we use it in any logic or computation? If we wish to represent it in one form or another then we can write a method to return that representation and have it call the getter(s).

get name () {
    return this._name
},
get age () {
    return this._age
},
getName () {
    return `The name of this person is ${this.name}.`
},
getAge () {
    return `This person is ${this.age} years old.`
},
getProps () {
    return `${this.name} is ${this.age} years old.`
}
3 Likes

I’ll say that depends on the use/purpose of the object, like I pointed out above get can be used for computation but I think in other cases it could just be used for formatting.
But at the end of the day, it’s a decision for the programmer/team how they choose to write their code.

2 Likes

Hello,

On your point regarding getters, do you actually need the getter to show temperature in different units? Even if you don’t use “get,” can’t you create a temperature() method that returns the temperature in whatever units you desire? I guess if you create a method temperature() without “get,” you can’t use temperature() to set?

Recently, I am finding the following resource a very good complement for my JS journey. For the above it did also help.
https://javascript.info/property-accessors

1 Like

(emphasis mine)
As far as I understood previous readings, writing getters and setters does nothing to stop access to the object’s properties, they are still directly accessible if one were to try it - correct?

  1. About methods that manipulate the values of properties: should they use the setter for that property or the “direct-access” syntax?

So in this example, which is preferable for eatTooManyTreats():

function dogFactory (weight) {
    return {
    _weight: weight,
    get weight() {
      return this._weight;
    },
    set weight(newWeight) {
      this._weight = newWeight;
    },
    eatTooManyTreats() {
      this._weight += 1;
    }
  }
}

or something like this:

function dogFactory (weight) {
    return {
    _weight: weight,
    get weight() {
      return this._weight;
    },
    set weight(newWeight) {
      this._weight = newWeight;
    },
    eatTooManyTreats() {
      set weight(this._weight + 1);
    }
  }
}

(I just realized I don’t understand how to call the setter properly…)

  1. Why is there no underscore in the definition of the getter/setter when the property name actually has one? So why does JS “know” we mean the _weight property when we write the getter like get weight() rather than get _weight().

  2. The usage of this is quite confusing to me.

get weight() {
      return this._weight;
    },

Here we have to explicitly state that we want to return the weight property of this object, and not some other one - but only in the function body! We are, however, not saying:

get this._weight() {
      return this._weight;
    },

(granted, it looks very tautological, but so does a lot of object oriented code), so the information which object we want to know the weight property of is missing from the declaration part, but have to state it in the function body. Why, though?

ad question 3.

The following experiment leads me to believe that JS doesn’t actually understand we mean the same thing by weight and _weight:

function dogFactory (weight) {
  return {
    _weight: weight,
    get weight() {
      console.log('Weight getter was called.');
      return this._weight;
    },
    set weight(newWeight) {
      console.log('You used the setter to manipulate the weight')
      this._weight = newWeight;
    },
    eatTooManyTreats() {
      this._weight += 1;
    }
  }
}

const jake = dogFactory(20);
console.log(jake);

jake._weight = 30;
jake.weight = 25; //prints: 'You used the setter to manipulate the weight'

console.log(jake._weight); //prints: 25 - not 30!
console.log(jake.weight); //prints: 'Weight getter was called.', 25

console.log(jake); prints:

{
  _weight: 20,
  weight: [Getter/Setter],
  eatTooManyTreats: [Function: eatTooManyTreats]
}

, as if _weight and weight were 2 separate properties.
But: both _weight and weight have a value of 25, even though “only one” of them was set to 25!

Man, how simple and great your explanation is, thank you very much!

1 Like

Sir, I wonder how can you teach us “learn how to write and use getters and setters and the world is your oyster” or “This will begin to make more sense when you get into real world programming…” while this is outside of your experience and you’re not able to furnish any real world example as you said???

Potential. If it is within one’s vision, it is for sure within one’s grasp. My own inexperience does not factor into the equation.


What does a getter do?

What does a setter do?

Those are real world questions. They don’t tear down the people they are being asked of.

1 Like

As if I am so obliged. You presume I am some teacher you have acquired. Show some respect. I am not that bought item.

1 Like

In this exercise I wrote this method and it didn’t get accepted:

eatTooManyTreats() { return this._weight + 1; } // when it should have been return this._weight++;

This was frustrating because I just couldn’t understand why my code was not excepted. I using “+1” actually wrong or is codecademy just trying to teach that using “++” is the better option?