Setters, set, and do not return. Getters, get (return) and do not set. Remove the return keyword from that line so the setting actually takes place.
Thank you for your answer.
Is it necessary to assign a random argument to the “age” function be used in the conditional in order for the “set” method to work?
const person = {
_age: 37,
set age(newAge){
if (typeof newAge === ‘number’){
this._age = newAge;
} else {
console.log(‘You must assign a number to age’);
}
}
};
The set age method requires a parameter, which in this case is tested to ensure it is a number.
person.age = 38
will pass that test,
person.age = 'thirty-eight'
will fail.
We can see that there needs to be a value in the assignment.
I have a question so I just realized setters can only hold one parameter. Is there a way for a setter to set an object into an array for a property. for example:
const team = {
_players: [
{
firstName: "Luffy",
lastName: "Monkey",
age: 19
},
{
firstName: "Zoro",
lastName: "Roronoa",
age: 21
},
{
firstName: "Sanji",
lastName: "Vinsmoke",
age: 21
}
]
}
I thought I could by making something called
set players({firstName,lastName,age}){
const player = {
firstName,
lastName,
age
};
this._players.push(player);
}
But that didn’t work
Not sure if you solved this one, yet. The first thing we discover is that we cannot use destructuring in the parameter, that I’m aware. But, we can pass in an array…
set players(player) {
[firstName, lastName, age] = player;
this._players.push({firstName, lastName, age});
}
Second, and perhaps more importantly, we need to have a getter for every setter.
team object
> team = {
_players: [
{
firstName: "Luffy",
lastName: "Monkey",
age: 19
},
{
firstName: "Zoro",
lastName: "Roronoa",
age: 21
},
{
firstName: "Sanji",
lastName: "Vinsmoke",
age: 21
}
],
get players () {
return this._players;
},
set players(player){
[firstName, lastName, age] = player;
this._players.push({firstName, lastName, age});
}
}
<- {_players: Array(3)}
> team.players
<- (3) [{…}, {…}, {…}]
> team.players = ['Joe', 'Green', 29]
<- (3) ["Joe", "Green", 29]
> team.players
< -(4) [{…}, {…}, {…}, {…}]
We pass in the array with the details for the new player. It gets destructured into the key names, and then restructured as an object in the push argument.
We could also use a single string, with a slight modification to the setter.
set players(player){
[firstName, lastName, age] = player.split(' ');
age = +age;
this._players.push({firstName, lastName, age});
}
team.players = "Mike Brown 24"
So if we make a setter, do we always have to have a getter that uses the same identifier?
Yes, they both use the same identifier…
get foo () {
}
set foo (value) {
}
The reverse is not the case, though. If all we need is a getter, then we would need to include a setter.
get foo () {
}
get bar () {
}
When we are setting a value it is imperative that no attempt is made to poll it, so the getter acts as a binding that cannot be broken until the setter is finished…
For step 4, the instructions read:
Use the
numOfSensors
setter method onrobot
to assign_numOfSensors
to100
.
Since the setter method is formatted like a function to receive an argument in parenthesis, why is the correct answer robot.numOfSensors = 100;
and not console.log(robot.numOfSensors(100))
?
How does simply assigning the value pass in the argument to be validated?
getters and setters are special methods, allowing us to tweak the read and assignment behavior of a property.
also, the property is _numOfSensors
, if you would do:
robot._numOfSensors = 100
you assign to the property directly, no validation takes place.
why use the _ before your objects?
before the properties you mean? Its a naming convention, to indicate a getter and/or setter is used.
Hello,
Can I pass two or more arguments to the setter in an object?
And why we set the value like this… robot.numOfSensors = 100;
instead of robot.numOfSensors(100)
Thanks
Short answer: no, we cannot pass multiple arguments. It’s a peculiarity of setters that must have a technical reason. Being as it is only setting a single property, it makes sense to have this constraint, though.
Again, this is an aspect of the background logic of the setter. One concern that ES authors wanted to address was asynchronous access. The getter is invoked when we invoke the setter so that the backing variable has a binding to it for as long as it takes the setter to complete its operation. It may not be concurrent, as such, only holding the variable until it is to be changed, then surrendered to the setter.
Bottom line, the setter does take an argument, but we don’t directly call it, only assign what that argument will be behind the scenes.
Thanks for your answer!
In the exercise both the get and set method have the same function name (numOfSensors).
Is this the only part of Javascript that breaks with the convention of using unique identifiers?
Or should we in fact always use the same identifier for both the get and set function if both occur in an object?
It doesn’t really break with convention but rather introduces a new special case. There is still a difference. One uses the special keyword, get
and the other, set
in front of the identifier.
Definitely, else they will not refer to the same backing variable.
this._prop: value // backing variable in object literal
this._prop = value // backing variable in constructor
get prop () {
return this._prop
}
set prop (newValue) {
this._prop = newValue
}
Thanks as always for the clarification!
Considering that this example given in the exercise
const person = {
_age: 37,
set age(newAge){
if (typeof newAge === 'number'){
this._age = newAge;
} else {
console.log('You must assign a number to age');
}
}
};
person._age = 'forty-five'
console.log(person._age); // Prints forty-five
the “parameter” newAge is set by doing objectName.propertyName = input
Would you be able to have multiple parameters for your set method? How would you input them?
Thanks!
That is a direct access assignment that bypasses the setter.
person.age = 'forty-five'
will use the setter and go through the validation.