I'm learning the basic syntax of classes in Javascript and an important question has arisen. Using the constructor I intend to create and set the property this.name
, while using the getters and setters I intend to get and modify this._name
assuming that _name is an 'internal' property of the object and therefore should not be modifiable without the use of the set. What I can't understand is the following:
"use strict";
class Admin {
constructor(name) {
this.name = name;
};
get name() {
return this._name;
};
set name(value) {
if (value.length < 4) {
console.log('Nombre demasiado corto!');
return;
};
this._name = value
};
};
let admin = new Admin('Julio');
//Por qué _name === name si todavía no he ejecutado el set?
//_name no debería existir, debería ser undefined
console.log(admin._name);
console.log(admin.name);
console.log(admin);
admin.name = 'Roberto';
//Por qué _name === name si el set no afecta a name, sino a _name?
//admin.name debería ser 'Julio' y admin.name 'Roberto'
console.log(admin._name);
console.log(admin.name);
console.log(admin);
//otra duda que tengo es porqué al mandar admin a consola, se muestra _name pero no name dentro del objeto
As you can see, my main doubt is regarding the set and the constructor, which add _name even though I have not executed the set.
We are going to analyze the assignments step by step and how they are traversed inside the function and why:
After defining the function you run this:
Which first goes through the constructor:
So far everything is correct, if the class did not have more methods we could access the property of the class through:
But it so happens that we have another method that affects what just happened, which is the set , which you put below:
And why does it affect? Well, if we go to this link , you will see that they say the following:
Let's stick with this sentence: a function that will be called when there is an attempt to assign a value to that property .
That is, the set also acts because inside the constructor that we have made? Well, that, we have tried to assign a value to that property
name
through thethis.name = name
, which has triggered the functionset
.And what does set do ? So at the end of the function do this:
That is, it has just created a new property
_name
with the same value of the assignment that we have seen in the constructor, because what we see in the parentheses as a parametervalue
is equivalent to what is assigned throughthis.name=
, that is, the parametername
of the constructor.So far the first question:
¿Por qué _name === name si todavía no he ejecutado el set?
and the short answer would be: Yes, you have executed theset
by assigning a value to the propertyname
in the constructor .Now we come to the second question:
¿Por qué _name === name si el set no afecta a name, sino a _name?
Well, if you go through the code you've given as an example in assign
Roberto
, you'll see your confusion. Take a good look at the assignment line:So, jumping from the bush, without thinking that there is a class behind, what do you see? I see an assignment to the property
name
of an object namedadmin
. Then it turns out that it is an instance of a class, okay, so then I deduce that it comes to the same thing but for a class instance, that is, an assignment to the propertyname
of a class instance represented by the objectadmin
. In the same way as before, without knowing what else the class does, nor if it has setters and getters, if we now did this:would return
Roberto
us But it turns out that it does have aset name
set, so it has to be executed by the same definition given before:And voilà, exactly the same thing that I explained before happens again, and the value is assigned to
_name
establishedname
, because that's what theset
at the end says:And so your second question is also answered:
¿Por qué _name === name si el set no afecta a name, sino a _name?
, that briefly the answer would be: You're right! The set does not affectname
, but it is the one thatadmin.name=
affectsset name
and triggers it, causing this second equivalence of values betweenname
and_name
.I don't know if you see it now or not, I have put it as I understand it and it fits me :-)
Tell us if now you also share this approach.
Simply, to know why it refers to _name, you have to understand what the backslash ( _ ) is used for in JavaScript:
Therefore, it means that you should not use these methods (which start with "_") outside of your object. Technically you can, but " _ " means you shouldn't. It will reference the variable, function, method, etc. that has the same name with which you created it.
@DarklceDust's answer isn't wrong, but it's not the reason your code behaves this way. Your getter and setter are named the same as your property: name . Somehow javascript (I'll try to find some source/documentation that supports this) creates a property
_name
this to avoid infinite recursion.By having this:
If you do this: you
admin.name
would be calling getter name which in turn executesreturn this.name
this you would be calling the same getter again and so on ad infinitum. Some IDE's or text editors like vscode throw an error having the code as in the example above. The convention is that in the get and set method you use the underscore to refer to the property and not to the get or set method .In fact, you can name the get and set methods differently from the property and thus avoid the underscore: