Jonas: So we learned
how to implement prototypal inheritance
with constructor functions
and then manually setting methods
on the constructor function's prototype property.
But now it's time to turn our attention to ES6 classes,
which essentially allow us to do the exact same thing
but using a nicer and more modern syntax.
Now, as I mentioned earlier,
classes in JavaScript do not work like traditional classes
in other languages like Java or C++.
So instead, classes in JavaScript
are just syntactic sugar over what we learned
in the last few videos.
So they still implement prototypal inheritance
behind the scenes but with a syntax
that makes more sense
to people coming from other programming languages.
And so that was basically the goal
of adding classes to JavaScript.
But anyway, let's now implement person using a class.
So we can write class and then the name
of the class.
And let's actually call it PersonCl.
So that stands for class.
And then curly braces like this.
And so this is actually a class declaration
but just like in functions,
we also have class expressions.
And so that would work like this.
So class expression.
And class declaration.
And so then you can pick whichever you like the most.
So it would be PersonCl,
and then class,
and then just like a function,
but without the arguments.
Okay?
And that is because, in fact,
classes are just a special type of functions.
So although we use the class keyword here,
behind the scenes, classes are still functions,
and therefore, we have class expressions
and class declarations.
Now, for some reasons,
I prefer the class declaration
and so I'm gonna use that right here.
And so this is how we write a simple class.
And then inside the class,
the first thing that we need to do
is to add a constructor method.
So just like this,
and this constructor actually works
in a pretty similar way
as a constructor function,
so as we studied previously
but this one is actually a method of this class.
And in fact, it needs to be called constructor.
So that is the rule.
But just like in constructor functions,
we pass in arguments basically for the properties
that we want the object to have.
So that's again firstName,
and then the birthYear.
Now, the act of creating a new object
actually also works in the exact same way as before.
So using the new operator.
And so therefore, whenever we create a new object,
so like a new instance using the new operator,
this constructor will automatically be called.
So let's actually try that right away.
And this time, let's create jessica here.
So new PersonCl
and so as you see, everything here
looks exactly the same as before.
So it looks just like a regular function call
and again, we also use the new keyword here.
And so therefore, just like before,
the this keyword here inside of the constructor
will also be set to the newly created empty object.
And so just like before,
we set the properties of the object like this.
So this.firstName is equal to firstName
that we receive and the same for the birthYear.
All right.
So basically, when we create a new instance here,
then it is this constructor that is gonna be called
and that will return a new object
and then that will be stored here into jessica.
So let's just log this to the console
and so, in fact, it looks just like before.
All right, so here we basically have the properties
that will be stored in the new object
that we want to create.
And so now it's time for the methods.
And the methods we simply write like this.
So we can simply add them here
and all we have to do is to write their name.
So just like a regular function in here.
So this is very nice and very convenient.
And so let's simply do the same as before.
So this.birthYear.
Now, what's important to understand here
is that all of these methods
that we write in the class,
so outside of the constructor
will be on the prototype of the objects.
And not on the objects themselves.
So this is really just like before,
prototypal inheritance.
And, in fact, we're gonna be able
to confirm that here.
So as we inspect this Jessica object,
when we look into its prototype,
then we will once again see the calcAge function here.
All right?
And so therefore, of course,
we're gonna be able to do this.
And actually, we don't even need to log it
to the console because the calcAge method
already does that on its own.
And so indeed, we get an age here.
And so one more time, let me prove to you
that jessica_proto__is equal
to PersonCl.prototype.
And it is true.
And so as you see, PersonCl here acts
just like any other function constructor
but the only difference that this looks a little bit nicer.
So with this syntax, we don't have to manually mess
with the prototype property.
All we have to do is to write the methods here,
so inside the class,
but outside of the constructor,
and then they will automatically be added
to the prototype property of the class basically.
So let me actually write that here.
So they will be added to the prototype property
of the Person class, which once again
is gonna be the prototype
of the objects created by that class.
And we can take this demonstration even further
by also adding a method manually
to the prototype.
So that's gonna work just as fine.
So let's create a greet method here.
So let's just say hey,
this.firstName,
and then we can call this on jessica.
So, of course, jessica.greet.
And so as you see that works just as well.
All right?
And so this is proof one more time
that the class really just hides the true nature
of prototypal inheritance in JavaScript.
So, of course, we could now do the same like this.
And notice how there are no commas between the methods.
Okay, so we could do this, take out this
and it would work the exact same way.
You see?
So this is great for people who are coming
from another language
and have experience with object-oriented programming,
because it's gonna be a bit easier
for these developers
to start writing object-oriented code in JavaScript.
Now, if you're one of these developers,
then please make sure
that before just starting to use classes,
you really, truly understand function constructors
and the prototype, and the whole prototype chain logic.
Now, to finish, I just need
to say a couple more thing about classes
that are important to keep in mind.
So first, classes are not hoisted.
So first, let's scroll a bit here.
Classes are not hoisted.
And so even if they are class declarations.
So functional declarations, remember,
are hoisted, which means we can use them
before they are declared in the code.
But with classes, that doesn't work.
Second, just like functions,
classes are also first-class citizens.
First-class citizens.
And so what that means
is that we can pass them into functions
and also return them from functions.
And as I mentioned before,
that is because classes are really just a special kind
of function behind the scenes.
And third, the body of a class
is always executed in strict mode.
Classes are executed in strict mode.
And so even if we didn't activate it for our entire script,
all the code that is in the class
will be executed in strict mode.
Now, right.
So keep these points in mind
if you want to work with classes.
So now at the end of this video,
you might ask if you should use constructor functions,
like we have been doing
or if, instead, it's better to just use classes.
And the first remark I want to do here
is that constructor functions
are not like old or deprecated syntax.
So it's 100% fine to keep using them.
So one more time, this is more a question
of personal preference.
Now, if you're asking if you should use classes
without understanding prototypal inheritance,
well, then the reply is definitely no.
Now, some people actually say
that classes are really bad in general
and that no one should ever be using them
simply because they hide the true nature of JavaScript.
But I actually don't agree with that,
and I think it's absolutely okay to use classes
in your code as long as you understand everything
that I just showed you previously
about the prototype and prototypal inheritance.
So you cannot just skip that part
because you want to become an expert
in JavaScript, right?
And you also want to feel conformable
while writing your code,
and that essentially means
to understand exactly what your code does.
So that's super important too
and so if you want to be confident,
you need to understand.
And so that's also the whole reason
why all over the course,
I'm going into such deep detail
into how everything works in JavaScript.
Now, what I personally like about classes
is that they visually put all the code
that belongs to a certain class,
so like all the data here
and all the behavior,
all into one nice code block like this.
With function constructors, in my opinion,
it all looks just like a big mess.
So like this.
I mean, in this case, it's just a little bit of code
but this can get out of hand pretty quick.
And in these situations,
I think that this actually looks at least a lot better.
But, of course, that is just my personal opinion.
What matters is that you start thinking about this yourself
and take your own decisions based on what I'm explaining
in these videos.