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

The last task of the Setters section reads:
To check that the setter method worked, console.log() robot.numOfSensors .

This doesn’t make sense to me. Shouldn’t we be checking that _numOfSensors was updated with the setter?
also, if I am wrong, is robot.numOfSensors calling the getter or the setter? Since both the getter and setter have the same name, I’m not sure what is being called here.

1 Like

get and set are special keywords that behave like properties, the name of which is the same for both because they both relate to the same backing variable (the one with the underscore prefix). We cannot call them directly because they are engaged in the background.

Above we must assume that the value has already been set, and we’re only polling the variable for its current value. When we write,

console.log(robot.property);

we are accessing the getter, which then returns the backing variable value the same way a typical object would, and when we write,

robot.property = "some value";

we are accessing the setter, but it depends upon the getter for some special binding which I don’t really understand well enough to explain but if you can handle dry technical reading, I recommend digging deeper into the relationship, and why setters depend upon getters in the first place. We can’t have set without get for the variable in question.

3 Likes

Yes! I get it now. Thank you @mtf!

1 Like

You’re welcome.

Aside

One thing you don’t want to do is create a circular reference. Consider the following code…

class Robot {
    constructor(foo, bar) {
        this._foo = foo;
        this._bar = bar;
    }
    get foo() {
        return this._foo;
    }
    set foo(x) {
        this.foo = x;
    }
    get bar() {
        return this._bar;
    }
    set bar(x) {
        this.bar = x;
    }
}

Notice how the setters are calling the getter, not the backing variable? That conflicts with what’s already going on in the background and pushes all the calls to a stack. The browser steps in and stops it eventually.

Uncaught RangeError: Maximum call stack size exceeded

That’s what we would call a fatal error. Keep this in mind going forward so you never make this mistake.

Bottom line, we cannot set and get a variable at the same time. Only set or get.

1 Like

Good to know . Thanks!

1 Like

the example logs the one with underscore also console.log(person._age);

Thank you - very helpful.

So would I be right in saying that within an object, setters and getters must always come in pairs with the same name?

1 Like

They only need to be paired if there is a need for a setter, which is optional. Setters require that a getter is present, but not the other way around. They will both have the name of their backing variable.

obj = {
    _member: 'value',
    get member () {

    },
    set member (newValue) {

    }
}
2 Likes

I don’t know if there any technical nuances as to why this works, but it seems not to matter whether you use the underscore or not. I reassigned the _numOfSensors property using the numOfSensors set method and by directly assigning the _numOfSensors property. I then called them using the underscore and without and both return the same thing:

So this brings up another question, why even use the set method if we can directly reassign the property?

Direct assignment does include validation, whereas the setter does.

Under this pretext, we would avoid ALL use of direct assignment anywhere in the program EXCEPT the setter (and getter).

Thank you guys for this entire conversation and also the one on getters it helped me understand the concepts very clearly you guys are awesome.