-: Let's now talk about a feature
that is actually common to all objects in JavaScript,
and that's getters and setters.
So every object in JavaScript
can have setter and getter properties.
And we call these special properties assessor properties,
while the more normal properties are called data properties.
So getters and setters are basically functions
that get and set a value so just as the name says,
but on the outside they still look like regular properties.
And so let's first take a look at getters and setters
in a simple object literal,
and for that I'm gonna use the bank account example
from the Bankist application.
So very simple object literal here.
The owner is Jonas.
Then some simple movements.
So the values here don't really matter, okay?
Oh, and of course I'm writing this object all wrong.
Maybe you have already been noticing that.
Okay, but now it should be correct.
All right, but now to add a getter to this object.
We can start by basically writing a normal method.
So let's say that we want a method
to get the latest movement and so let's call it latest.
And then to transform this into a getter
we simply prepend the keyword get.
All right, and so let's simply return the last movement here
so that's this.movements.slice -1.
But this is actually gonna return an array,
so an array with the last position
and so we can simply take that out using the pop method.
And we could've used destructuring as well,
but I didn't want to save this
into an external variable first.
And so now we can use this getter like this.
So account and then we say latest,
but we simply use it as a property.
All right, so we don't call the method,
but instead we write it as if it was just a property.
So let's see, and indeed that returns 300.
So this can be very useful
when we want to read something as a property,
but still need to do some calculations before.
Okay, and now we can do the same also as a setter.
So we say set, latest again
and then here we can basically add a new movement
to the array.
And any setter method needs to have exactly one parameter.
So in this case that's simply a movement.
So let's say this.movements.push
and then that movement that we just passed into.
Now it is not mandatory to specify a setter
when we have a getter for the same property.
Okay, so just a getter or just a setter would be enough.
And so, how do we use the setter now?
So if it was a regular method then we would have to do this.
So account.latest and then call it with the movement,
let's say 50.
But now this is actually like a property and not a method.
And so we can simply set it
just like we set any other property.
So we essentially set it equal to 50.
And so now if we take a look at the movements here,
it will then give us the complete array
with the 50 there at the end.
And so in a nutshell this is how getters and setters work
for any regular object in JavaScript.
Now however, classes do also have getters and setters,
and they do indeed work in the exact same way.
And so let's try them out now here in our person class.
So here we can for example add a getter
for the age property.
So we can say get age and then we return the age.
So this is of course very similar to the calcAge method
that we already have here but that doesn't matter
because this is really just a demonstration example.
All right, and so like this we will be able
to basically read the age of any object using a property.
So let's try that here for example, jessica.age,
and this time we actually need to log it to the console.
And you see here we now get the same value.
All right, so you see that the getter is indeed
just like any other regular method
that we set on the prototype.
And in fact we can also check that out here.
So if we take a look at the prototype of Jessica,
it will be right there.
Now it has these dots here
because it's only calculated once we actually click this.
Okay?
So here too it already looks as if it would be a property
and not a method.
We still have the get method down here,
but then it's also kind of ended as a property.
All right?
So that's a very simple use case of a getter,
but setters and getters can actually be very useful
for data validation and as an example,
let's try some validation with the name.
So for that I will actually change a firstName here
to fullName.
And so now here we expect a full name.
So a name which basically contains a space.
So let's say Jessica Davis here,
and so now we can create a setter for the fullName property
which will check if this is actually a full name.
All right, so set fullName,
and then we need the name itself,
and then here we need some logic.
So to test if it contains a space,
if the name includes a space,
and I'm not sure if it is called includes actually.
Now let me just test it here very quick.
Okay, we have to comment out this part.
All right, so this method actually does exist.
So I wasn't sure if it only exists on erase,
but indeed it also exists on strings.
And so in this case then we actually want to set
this.fullName to the name that was received.
But if not, we want to give an alert.
So the given name is not a full name.
So in this case what's really important to understand
is that we are creating a setter for a property name
that does already exist.
So fullName is already a property
that are trying to set here,
but then we also have the setter.
And so now what's gonna happen is
that each time this code here is executed,
so whenever we set the fullName on the this keyword,
then actually this method here,
so this setter is gonna be executed.
And so that name that we pass in as fullName
will then become this name.
All right, let's check that out actually.
And so now as we create Jessica here,
you will see and indeed it, we saw Jessica Davis here,
but now we got this crazy error here
of maximum call stack size exceeded.
Now that's a very cryptic error message,
but what happens here is that there is a conflict.
So right now both the setter function
and this constructor function
are trying to set the exact same property name.
And so that gives origin to this weird error.
So what we need to do instead
is to here create a new property name.
And the convention for doing that,
so when we have a setter which is trying to set a property
that does already exist,
then here as a convention we add an underscore.
So again, this is just a convention,
it's not a JavaScript feature.
So it's really just a different variable name
to avoid that naming conflict.
However, now when we do this,
we are actually creating a new variable,
so a fullName variable.
So let's try this now actually.
So if we try to look at Jessica Davis you see that right now
the property that exists is underscore fullName.
And so right now we cannot do jessica.fullName
because that simply doesn't exist.
And so to fix this we now also need to create a getter
for the fullName property.
And so that will simply return the underscore fullName.
So let's see.
So return this._fullName.
And so if we try to do the same now,
then you see that we are back to having this fullName here.
All right?
And of course, the actual property that is here
is now still underscore fullName,
because well that's what we do here in the setter, right?
But then we can also compute this full name
just as we can compute the age.
So this pattern here is important to understand
whenever we try to set a property that already exists.
Now let's try another name here just to see what happens,
and actually after all this.
So let's create a Walter object here.
New PersonCl, that's right.
And now we're just using a name with one word,
let's say 1965 and so now we get this error.
So Walter is not a full name,
and so right now if we check out Walter,
age probably doesn't have any name, and yeah it doesn't.
So just the birth year now.
But if we then put it as a full name,
so Walter White then indeed, Walter like this,
then we get the underscore fullName.
But just like before we can then also access walter.fullName
because of that setter or actually of that getter
that we just defined earlier.
Now okay, great, so this is another nice feature of classes
that can be very useful sometimes.
Now we don't need to use getters or setters,
and many people actually don't,
but yeah, as I just said sometimes it's just nice
to be able to use these features
and especially when we need like a validation like this
by the time we are creating a new object.
So that's essentially what this setter here does.
Next up,
we're gonna take a look at yet another feature of classes,
which is static methods.
So let's check that out right now.