Don't we need to check `_numOfSensors` instead?

Either way will work, but using the setter method allows you to make sure that the property is set in a way that you intend.

With the numOfSensors property, if you set it directly using _numOfSensors, you can set it to anything - a string, Null, false, undefined, another object - there’s nothing to flag it as an error. By making a set numOfSensors method, you can check the input to make sure that it is a valid number before assigning it to _numOfSensors.

For example, you may have other code that depends on the _numOfSensors property, and maybe if _numOfSensors is accidentaly set to a string instead of a number that code will not work properly. If you give a setter method it’s less likely that the _numOfSensors property will be set to an invalid value, since the set method would catch the error.

1 Like

What do you mean by "we’re only polling the variable for its current value." ? If we assign a different name to the setter here, will it not be less confusing? and why does the value of _numOfSensors (i,e 15) also get logged in when i assign a string to the setter?
Here is the code, please elaborate
const robot = {

_model: ‘1E78V2’,

_energyLevel: 100,

_numOfSensors: 15,

get numOfSensors(){

if(typeof this._numOfSensors === 'number'){

  return this._numOfSensors;

} else {

  return 'Sensors are currently down.'

}

},

set sensors(num){

if (typeof num === 'number' && num >= 0){

  this._numOfSensors = num; 

} else{

  console.log('Pass in a number that is greater than or equal to 0');

}

}

};

robot.sensors = ‘sdf’;

console.log(robot._numOfSensors);
Output: Pass in a number that is greater than or equal to 0
15

Hi, I know that I am new to the conversation here. Please correct me if I’m wrong in my understanding of getters and setters. Is it right to say that getters essentially help to call an object faster than just say making a function and using dot notation? And that setters change the original value of the property of that object if so needed? Just looking for the simplest, most direct answer. Thanks.

By conventional means we access and write object properties that exist using dot notation.

console.log(object.prop)
object.prop = 'value'

Getters operate with the same syntax but offer an additional layer of abstraction where we can process the data from its original source without altering the data. The data could be secured as one type and accessed as another, if so desired.

Setters can operate along the same lines. They use conventional syntax but have a layer of abstraction that can validate and/or modify type for the purpose of storing. What we do with a setter does alter the original, but only according to the set rules this software layer affords us.

One suspects it is possible to even validate instance parameters through clever use of the setter, though pure speculation, mind. Accessors are a part of OOP and even if they are more decoration in JS than anything fundamental, it bears learning how to incorporate them into one’s code architecture for the sake of future friendliness, and to develop habits that easily flow into other OOP languages.

2 Likes

Hi, but we are not talking about assignment specifically in the thread( if we are I am more confused that I already feel). We are talking about logging it to the console. Both the underscore (original property value?) and the non underscore (setter property value?) work to call the value to the console. My question is why it matters which you use to call the value? Does it have to do with there they point or where the value is stored? Will there be repercussions if I try to call the value with the original property value?
Thanks for any help,

JS doesn’t have private variables, only a mock up of that feature by letting us implement setters and getters that access the underscore variables. Bottom line, if you wish to access properties directly, then drop the underscore (and setters and getters) and resort to the ES5 methodology. It’s our choice. Think of how we can take advantage of setters and getters. Leverage their benefits and possibilities.

Thanks, sorry Ive only been doing this 3 weeks or so and I dont have a CS degree. I am not sure I understand you response. Ill just stash it away as an item to revisit as I get farther in to the theory…for now ill just trust ya. :slight_smile:

1 Like

Yeah, set this question aside and revisit it when you get some more exercises under your belt. Keep an eye on the ways that setters and getters can be used to validate inputs or dress up outputs. The goal is to never expose the underscore variables (except in setter/getter).

@mtf Ask me please! Do we have to name setter and getter like variable or it’s just good manner?

I’m mind blown with this explanation. It gives a lot of clarity of the concept.
So it is as if every property had attached default properties get and set (with a function inside them, with no parameter and returning the value, in the case of get and with one parameter returning the reassignment of the value to the parameter in the case of set) and when we create get and set methods we are “reassigning” those default properties to the functions of our liking?

1 Like

Getters and setters in JS are largely syntactic sugar. The actual values are stored in their backing variable (_var), with get and set standing in for the normal property name. They are special functions, with unique behavior built in to the background.

1 Like

In a sense, isn’t the language itself a syntactic sugar?
I’m a newbie, and have no idea what is happening in the background, but I suppose that is a more complicated, or at a lower level of abstraction, code, that is more accessible for the computer to “understand” it as it “translate” it to the JavaScript syntax.

I was supposing that

Obj.property;
Obj.property = 'foo';

had a code in the background that, if “translated” to the higher level of abstraction, would work as functions with each and every property as parameters (I don’t know if only when called) and the getters and setters would be functions that reassigned the default ones in the background.

They are special functions, with unique behavior built in to the background.

Does that mean my guess was wrong? That is, creating getters and setters call functions from the background that are independent from the default ones?

get property () {
  return this._property;
}
set property (value) {
  this._property = value;
}

In the background there is a variable, property. If you inspect the code in Chrome you’ll find it. The getter plays an important role when we invoke the setter: create a binding to the variable so it cannot be accessed while being changed. That’s part of the magic going on in the background. When we write,

obj.property = 'value';

JS calls the getter, to bind the property, and the setter to assign the new value. It gets assigned to both the hidden, normal property, and to the backing variable, per the method.

My own knowledge does not go deep enough to give more technical details, so forgive me if I’ve given that impression. For now, best advice would be to acquaint yourself with the syntax and usage and get that down. At least we can both do that.

1 Like

Just a precision, the following line :

this.foo = x

does not call the getter, we’re calling the setter.
It’s an infinite loop of calls to the same function (the setter), hence the fatal error.

Not necessarily. But it’s a very recommanded good practice. Else, you will have to remember how you named each of them.

The following is an advanced explanation of the setter and getter, but once undertood, it makes their use very easy.

The Setter and Getter behave like any other method, except for the following thing :

  • ‘get’ is a decorator that allow us to acces a method of an object without using parenthesis. The method that we decorate with ‘get’ should take no parameters and usually returns something. Aside from this, the method we decorate with ‘get’ behaves like any other method.

To understand this, take a look at the following code :

const niceRobot = {
get myGetter() {
console.log(“i’m just like a regular method, but i usually return something, and you don’t need parenthesis to call me.”)
return 100
}
}
console.log(niceRobot.myGetter)

Notice how this getter ‘myGetter’ doesn’t read any other properties of the niceRobot object. it’s just a method that returns something. The only difference is that we call it using “nicRobot.myGetter” instead of “niceRobot.myGetter()”, because we used the decorator ‘get’.
However, the most important and recommanded use of getters, is to track properties of the object. In this case, it allows us to perform some operations (like validating or formatting) before returning the values of the properies.

  • ‘set’ is a decorator that allow us to access a method of an object without using parenthesis using the default setter of javascript : referencedData = newValue. The method that we decorate with ‘set’ should take exactly one parameter. Aside from this, the method we decorate with ‘set’ behaves like any other method.

To understand this, take a look at the following code :

const niceRobot = {
set mySetter(newValue) {
console.log('i'm just like a regular method, but i must take exactly one parameter, and you can use me like this : “object.mysetter = newValue” instead of “object.mySetter(newValue)” ')
// Do whatever you want with newValue
console.log("You just passed the value " + newValue + " to niceRobot.mySetter method ")
}
}
niceRobot.mySetter = 1337

Notice how this setter mySetter doesn’t access or modify any other properties of the niceRobot object. It’s just a method that does something we want with the newValue parameter that we passed to it. The only difference is that we call it using “nicRobot.mySetter = newValue” instead of “niceRobot.mySetter(newValue)”, because we used the decorator ‘set’.
However, the most important and recommanded use of setters, is to modify properties of the object. In this case, it allows us to perform some operations (like validating or formatting) before assigning the values of the properies. Note that for this case, we need to store the values in a dedicated property that we generally denote “_propertyName” to distinguish it from the setter and/or getter. We need this distinction because the setter/getter do not directly store values, since they are functions, not mutable data variables.

The main other differences between a usual object method, and a setter/getter method are :

  1. The ‘set’ and ‘get’ decorators locks the associated key. This means that we cannot modify the value of that key to anything else. The following code explains this :

const niceRobot = {
myUsualMethod() {
//A usual method
},
get myGetter() {
// My getter
},
set mySetter(value) {
// My Setter
}
}

console.log(niceRobot); // Output : {myUsualMethod: [Function: myUsualMethod], myGetter: [Getter],mySetter: [Setter]}
niceRobot.myUsualMethod = 1;
niceRobot.myGetter = 2;
niceRobot.mySetter = 3;
console.log(niceRobot); // Output : { myUsualMethod: 1, myGetter: [Getter], mySetter: [Setter] }

Notice how the value of the ‘myUsualMethod’ key was modified, while the values of ‘myGetter’ and ‘mySetter’ were not modified. They are locked due to the decorators ‘get’ and ‘set’.

  1. The setter and getter can have the same name without overwritting each other, unlike usual methods. The way JavaScript differenciates between the two is the calling syntax. If you call that name using an assigning method (object.method = something) it will use the setter, if not it will use the getter.
    On the other hand, note that : a usual method can override a setter/getter and a setter/getter can override a usual method.

  2. As a consequence of all the above, if you don’t assign a return to the getter, calling the getter will return “undefined” (Just like any other method without return).

  3. As a consequence of all the above, if you have a setter, but don’t have a getter with the same name, calling the setter (for example with console.log(object.mySetter) ) will return “undefined”. But if you have a getter with the same name, the call is automatically forwarded to the getter).

So, apart from those main differences and the call syntax difference, a setter or a getter will behave like any usual method, and you can do whatever you want with it. If you do the excercice again keeping this in mind, you will easily understand what the setter and getter actually does.

I hope this doesn’t complicate things for anybody. But do not hesitate to read the documentation on this, and ask questions to fully understand this.

1 Like

get tells JS to define a property. That is not decoration, but declaration.

So basically the purpose of set is to pass into the object only such a property value that first passes the if condition and is therefore in a valid and desired format.

Aye. It gives us more control over what gets written to our variables. This is especially useful when our inputs are custom objects, or rather. need to be. Without a setter this level of scrutiny would not be possible.

Thank you for an informative thread, my understanding at a rudimentary level is that getters get and return properties depending on the outcome of a conditional, and setters can reassign existing values indirectly and under certain conditions.

Must we ALWAYS have a getter to utilise a setter? Is it absolutely necessary or just good practice? Why?

const anotherPerson ={ _age: '37', set age(newAge) { if (typeof newAge === 'number') { this._age = newAge; } else { console.log('You must assign a number to age'); } } }; anotherPerson.age = 40; console.log(anotherPerson._age);

This logs to the console as expected, no getter required. Why?
…and thanks!