Let's keep exploring objects
and this lecture will bring us to object methods.
So we learned that objects just like a race
can hold different types of data.
And they can hold even a race,
and in fact, they could even hold objects inside objects.
But now we can take it even further.
And for that, remember how I said
that functions are really just another type of value.
And if a function is just a value
then that means that we can create a key value pair
in which the value is a function.
And that then means that we can in fact,
add functions to objects.
And so let's now see how.
And once more, I will get back this object here
but we will change it up a little bit this time around.
So here let's simplify and just put the birthYear.
So just 1991.
And I also want to add a Boolean here, hasDriversLicense.
Just to show you that we can hold all kinds
of different data types in one object.
But now let's also add a function here as a key value pair.
So to do that, all we have to do is to add another key here.
And the function that we want to add is again,
the calcAge function.
So that's one of the favorites, as you can see,
but it is because it's a very simple calculation
that we can do with the birth year.
So to do that, let's simply add the name
basically off the function here as a key.
So as a property,
so calcAge and then the colon, and now here
we simply specify the function as an expression
and that works because the expression produces the value.
And so we can just do this,
so function, and just like before ,
we pass in the birth year
and we return 2037 minus the birth year that was passed in.
So this is pretty similar to simply writing this, right?
So a regular function expression.
So const calcAge like this,
this is how we used to do it before.
And so you see that this is pretty similar.
The difference is just in the syntax
because now calcAge is not a regular variable like here,
but it's a property of the Jonas object.
And so therefore we use the colon here
but the rest here is exactly the same.
And so that's why it was very important
that you understood what a function expression actually is
because here we need to function expression
to create this method.
And that's what this function is called.
So any function that is attached
to an object is called a method.
So of course we could have not used
a function declaration here.
So something like this,
so function calcAge, for example, that would not work,
we would certainly get an error here.
So unexpected token function,
because this is a declaration.
And so it doesn't work here,
here, we need an expression.
And so this will work indeed.
Okay? Does this make sense?
So if you can think of functions as simply being values
then you can see that a method is actually also a property.
It just happens to be a property
that holds a function value.
So here we have a string value,
here we have an array value,
here we have a Boolean value,
and here we have a function value.
All right.
So, I hope that's logical.
And now just like we can access any other property,
we can also access the calcAge property or method.
So jonas.calcAge and so calcAge is now the function value,
and just like any other function in order to call it,
we use the parenthesis.
And now we can pass in the year here.
And so that should then calculate our age.
And let's just unlock this result to the console here,
just to see if everything works.
And it does indeed.
Okay. And you could also have access
to this method using the bracket notation,
because again, it's just as if it was a normal property
and the brackets would actually be necessary here
so that this then here is the function
and then we call the function using the parenthesis.
So let's try that.
And, yeah, here this needs to be a string.
So like I showed you in the last lecture,
and now here we get 46 as well.
Okay. So just like I showed you in the last video
with the operator proceedings table,
the first thing that happens here,
is that jonas.calcAge is computed.
And so this here will become the function value.
And then with the parenthesis,
we call that function value here and passed in 1991.
And the same thing here,
so here we access the property calcAge using the brackets
and then this here will basically be replaced
with the function,
and then we call the function right here, just like before.
All right, now you might have noticed
that the birth year 1991,
that we passed here as an argument to the method
is actually already defined
in the Jonas object itself up here, right?
So we already have this information in the Jonas object.
And so writing the same number here and here is not ideal
because we might make a mistake and pass in the wrong year.
For example, right here.
So Jonas' birth year is 91
but here, we could, for some reason accidentally do 92
and then it would be wrong.
And even if we do not make any mistake,
this is still not ideal
because we are not keeping the code dry.
So we're violating the don't repeat yourself principle.
So if we know the birth year of Jonas,
it would only be written in one place,
not in multiple places,
because if that might change,
then we have to change it everywhere.
That's always the philosophy that we need to keep in mind.
So what if we could actually access this birth year property
directly from the Jonas object
instead of having to pass it in?
Well, it turns out that we actually can,
and that's because in every method,
JavaScript gives us access
to a special variable called this.
And so what we can do now is in this calcAge function,
we can read the birth year directly
from this object itself without having to pass it in
as a parameter here into this function.
Alright, so let me copy this and comment this one out
just so that we keep a record of what we did
but this here will be the new version.
So now we no longer need this parameter
and we will read the birth year directly from the object.
And for that again, we will use the this keyword.
So the this key word
or the this variable is basically equal to the object
on which the method is called,
or in other words,
it is equal to the object calling the method.
So, let's see who is calling the method.
So down here, here is calcAge,
and the object that is calling the method is Jonas,
because that's where the dot is.
And let's forget about this one,
actually comment it out here.
And so again
the object that is calling the calcAge method here is Jonas.
And so that means that inside this method
the this variable or the this keyword will point to Jonas.
And so let me just write this.birthYear here
and then I can explain it even a little bit better.
So, here we don't need to pass the 1991 here
and I will run this now and we still get the correct result.
So, great.
And to make this even more clear here,
let's also log this to the console,
and indeed, this is the whole Jonas object.
And so again, that's because the Jonas object
is the one who is calling this method,
so this function,
see here, it's jonas.calcAge
and so whatever appears before the dot
is the one who is calling the method.
And so therefore, in the method,
this points to Jonas now,
and if this points to Jonas,
then this.birthYear is of course
this value that we have right here.
Great.
So you see that the this keyword
is something really, really useful
and we will learn even more about the this keyword
in greater detail in a later section.
For now, I just wanted to introduce you to this concept
and I noticed can be a bit confusing.
So really make sure to maybe pause the video
and really analyze what's happening here.
Maybe you can even rewind a little bit
and hear my explanation again,
that might be useful too.
Now you might argue that maybe we don't even need
this confusing this keywords.
Why not just do jonas.birthYear, here instead?
Well, because that would actually still violate
the don't repeat yourself principle.
It would work just the same here now,
but then let's say
that we need to change the name of the object.
So we change it here to Jonas2
and then we call Jonas2 down here,
and then the code will no longer automatically work,
because now Jonas is not defined of course.
And so we would have to keep that in mind
and then come here and manually change this as well,
while if we had the this keyword,
then everything will keep working
without us having to change it there,
because now this will simply point to Jonas2,
because that is the object calling the method.
And so therefore it's always a good idea
to reference the object itself
and not hard-code the name of the object.
So let's put it back to Jonas and yeah, much better.
So this works great already,
and we're really going
into some more advanced territory here.
So I hope you're still following me
and you're still making sense of everything.
However, we can actually even take this a little bit further
but don't worry, it's not going to get a lot more confusing,
just a small variation of this,
because let's say that we need to access
the age multiple times throughout our program.
So that would be like calling this a couple of times.
So let's say in three places of our application,
we need to access the age,
and so, of course this will work,
and indeed it does.
And it always locks the Jonas object
because we still have this here.
So this makes it a bit easier to view.
And so what happens here
is that a function will get called a total of four times.
And so this computation here will be done four times.
And in this case that's not a big deal
but it might be a like a heavier computation
that actually takes some more time,
and so it would be a bad practice to do this multiple times.
Instead, what we can do is to just calculate the age once,
then store it in the object,
and then when we need it at a later point,
we can then just retrieve the age
as a property from the object.
So, I hope you're following me here.
So I will again copy this and comment it out
so that we keep all the three versions that we did here.
So, what I was trying to say
is that we can now use the this keyword
also to store a new property.
So, we can say this.age is equal to this here.
So we calculate the age,
and then we create a new property on the current object.
So in this case, on the Jonas object,
and remember that we can use the dot notation like this
to create new properties.
So we did that in a previous lecture as well.
Where was that?
Yeah, right here.
So here we created jonas.location
and set it to Portugal.
And so here we are essentially creating jonas.age
and setting it to this age that we just calculated.
And then we can simply return this age.
And of course we don't even need to return anything
if we didn't want to.
We could make this method only calculate the age
but not even return it,
but I think it's a good practice
to actually also return it.
And so now here we can replace the function call
with simply a request
for the age property,
and notice this trick that I did here again
with the command D, right,
So this gives me multiple cursors
and then I can do one operation
in multiple places at the same time.
So that's a really handy shortcut.
So, again, command D, or control D
and in the menu bar that means add next occurrence.
So let's test this and the results should be the same,
and it is, but we only needed to calculate the age once
then from here,
we simply retrieve the property
that we had already calculated before.
And so this is the most efficient solution let's say.
All right, and now I actually have another,
a small challenge for you
that you can do just in this video.
So I want you to write a method called getSummary
and this method should return a string
which should kind of summarize the data about Jonas,
or, of course, any other person data
that you might have used.
For example,
let me again,
actually we can get rid of this.
So let me write Challenge here again
and then do an example string.
So I want you to write for example this,
Jonas is a 46 year old teacher.
And we now could actually add all the data here
to the string,
but that would be too much work
and I'm a bit lazy now.
So let's just also say if I have a driver's license or not.
So Jonas is a 40 year old teacher
and he has a driver's license.
And it says that I have a driver's license
because it hasDriversLicense is true
but if it was false, then here, it should say
and he has no driver's license.
So it's either a or no.
So figure out how you can do that,
and so I hope you manage to do it.
It's a bit similar to what we did in the previous lecture
but this time I want you to actually write a method
on your own.
So give this a try and I see you here in a second.
Okay. So let's add getSummary
and remember that you to a need to have a comma
between the properties.
And so that's true also with methods,
so here we need a comma,
and then just a function
and it will then get all this data of course,
from the current object.
So actually let's first call this method,
so, and we're doing it inside of console log,
log because of course,
we want to be able to see the summary string
as a message in the console.
So jonas.getSummary.
Okay. So, which is the object calling the method?
It is Jonas.
And so therefore, the this keyword inside of getSummary
will be Jonas.
So I hope that this one is clear at this point.
So let's now build a string here,
and starting with the name,
it is at this.firstName is a,
and now the age,
so this, and now what do we do here?
Should we use the age property, or should we do calcAge?
Well, I would say that we should do calcAge
because we cannot assume that calcAge
was already called before.
Okay.
And if we don't call calcAge before we call getSummary
then the age property would not exist.
And so,
and so it's, it's better to actually do calcAge here.
And so I think we did this before,
so in a template string, we can easily do a function call.
That's not a problem at all.
So this.calcAge will call this other method
and this will then return the age.
Alright. And maybe it might be strange for you
to call the function also on this,
but well, the rule is just exactly the same.
This is Jonas in this object,
and so this is essentially the same as writing it here.
Alright. So this will become the age
and so, year old,
and now the job, jonas.job,
and he has,
and now we need to decide between a and no.
So let's do a turnery operator here.
So we get this.DriversLicense,
and basically if it's true
then we want the results of this operator to be a,
and if not, we want it to be no.
And then driver's license.
Okay? Makes sense?
So again, here we want either a or no,
depending on the state of the hasDriversLicense property.
So we get that property
by calling this.hasDriversLicense
and here we're using the turnery operator.
And so if this first part is true
then the result of the operator will be a,
and otherwise the result will be no.
And so that's what will then be put
into this place of the sentence.
Okay. And we already called the method down here
and we logged it to the console,
and so I think this should work now.
And it does.
So Jonas is a 46 year old teacher
and he has a driver's license.
Now just to test, let's set it to false and no,
and he has no driver's license.
Beautiful.
Okay.
And yeah, that's all the code
that I had to show you in this video.
And now just to finish the lecture,
which I know is already running quite long,
but I want to basically build a bridge
between this method and the array method lecture.
So remember that we used methods on a race previously,
so we can quickly go there.
So it was before this challenge.
Yes, indeed.
So for example here we have friends.push.
And so we have an array and on there we call a method.
So just like we did in this video,
now what this means is
that arrays are actually also objects,
they are just a special kind of object.
And so they have functions, or in other words
they have methods that we can use to manipulate them
like push, pop, shift and unshift and many more.
All right? So in this lecture,
we created our own methods on our own objects.
But here we basically used built in methods on a race.
And so once again that means
that the race are actually also objects,
that's why they can have methods as well.
And we will dive deeper into why things work like this,
but I wanted you to realize this early on in the course,
this is quite a complex topic,
and so there is really a very exciting journey
still ahead of you.
So I hope you're enjoying this journey so far.
And now to test your knowledge,
there is coding challenge number three, coming up next.