Now we are coming closer
to asynchronous code
and therefore, the end of this section
but before we get there,
there is another concept related to objects,
which I'll explore again.
And for that, I'll add a new objects.js file,
and in there, of course, we learned
that we can create objects like, let's say a job
that might have a title: developer,
that might have a location: New York.
And maybe a salary of 50,000 a year like that.
That's how we can create objects.
We can also split the key-value pairs
into multiple lines to improve readability.
And that is something we used over and over already
in this course.
We then can use the job notation
to access those properties,
and we can also add methods,
which are simply functions added as properties,
as values inside of that object.
That's what we already learned.
Now, in this course, you also sometimes saw
that I created objects with a special new keyword.
For example, when we created a date.
That's something we did earlier in the course.
Date is actually a built-in thing in JavaScript,
both in the browser, as well as NodeJS,
and when we call new Date,
we create a new object that describes a date.
By default, if we call it like this,
it gives us the current date and timestamp.
And we can then call methods on that date,
for example, toISOString
to get a standardized string representation of that date.
So if I console.log new Date like that here,
and I then execute objects.js,
I get this output of the current date timestamp.
But what is this new keyword
and what exactly is this Date thing,
which we execute like a function?
Now, Date here, in the end,
is a so-called constructor function or class.
And constructor functions/classes,
we can treat these terms interchangeably here,
are blueprints that allow you
to build objects based on them.
What we did here with the job
is we used the so-called object literal notation,
which means we create an object when we need it
and we manually describe all the key-value pairs we need.
And often that's exactly what we want
if we just want to group together a couple
of pieces of data.
But what if we would be building an application,
a website that needs multiple jobs
that all have the same shape but different values?
If we build a website that allows users
to manage different job profiles,
we might, under the hood, create multiple job objects
but will have differing titles, locations and salaries.
Now, we can create multiple jobs,
simply by repeating that object literal notation
over and over, for example,
by copy and pasting this
and then filling in different values.
That is, of course, something we can do,
and with that, we can then definitely
also build multiple objects.
But if you have scenarios like this
that you potentially need multiple objects
that have the same shape,
a blueprint can come in handy.
And Date is a good example.
It's not unrealistic that you have different kinds
of dates in your application
and therefore, it's actually even built in
in JavaScript, and you have this standardized blueprint,
which does a lot of things under the hood,
for example, it gives you the current date.
And it also gives you utility methods
for converting and outputting that date.
And very often as a developer,
you will work with such built-in blueprints,
such built-in classes or constructor functions
but you can also define your own ones.
And for that, let me comment all of that out,
and let's create our own blueprint for a job.
In modern JavaScript,
which is supported both in NodeJS,
as well as in the browser,
we do this by using the class keyword.
A class is simply a blueprint for an object.
Then we give this class a descriptive name,
for example, Job.
Now the naming convention here is that we typically start
with an uppercase character for those classes,
just as Date starts with an uppercase character.
Now, we then have curly braces
and inside of that block of code
that belongs to this class,
we can now define this class.
And we do this by adding a special method here
by writing constructor like that.
This adds a method to this class
and we can also add our own methods.
We'll do this in a second.
But this is a special method
with a reserved name
that basically tells JavaScript
how to construct a concrete instance of this class,
how to construct a object based on this blueprint
when you later use this Job class
in conjunction with the new keyword
because we now can create jobs like developer
by using new Job like that
so by executing our class like a function
by adding parentheses here
and by adding the new keyword.
This is how you can use your own classes,
your own blueprints
and that will automatically execute this constructor method,
which is added in the class.
And you need to add that to then run any logic
whenever this code here is executed,
whenever you create an object based on that class.
Now, in this constructor, you can do whatever you want.
For example, the built-in Date class
will reach out to the system
and find out what the current date and time is.
You could do something similar here
but here, I instead just wanna add a couple of properties
to the object that should be created.
And you do this by using a special keyword,
another special keyword
that's built into JavaScript,
and that's the this keyword.
This simply refers to the object that will be created.
And hence, you can use the dot notation here
to read or write properties
and since we're in the constructor,
and no properties exist yet,
we can simply assign a couple of properties
that will then be added to the object that is created
because again, this refers
to that to-be-created object here.
And here we could, for example, add a title
and then set this to any value of our choice.
For example, Developer.
But typically, you don't wanna hard code a value here
in the constructor but instead,
it would be nice if we could pass the concrete values
to that constructor when we create our object based
on the class with the new keyword.
And that's why we call it like a function.
Date doesn't necessarily need any values passed here.
For our own Job, that might be different.
We could expect the jobTitle here as a parameter
because constructor, even though it's a special method
still is a method in the end,
so it's a function in the end,
and hence, you can pass in parameters
and we can then use this parameter value here
to assign it as a value to this property.
And similarly, we could accept a place and a salary,
and then also add this.location
and set it equal to place,
and this.salary and set it equal to salary.
And as you see at the example of salary,
you are allowed to use the same name
for the parameter as you do for the property,
but as you see at the example of location and title,
it's not a requirement to use the same names.
It is up to you.
But now with that,
you can pass your concrete values here
as values to new Job.
So Developer and New York
and 50,000,
and just as with every function call,
the order does matter here.
So we have jobTitle, place, salary here.
We need to keep that order
when we pass the concrete values.
And then with that, we'll build such an object.
Now if I console.log developer here in the next line,
you will see that if we execute this code in objects.js,
this object is being output here.
We also get the name of the blueprint that was used
as a extra convenience by NodeJS when we use console.log
but we also can see all the properties of that object.
And what's really important to me here
is that the object we get by using this blueprint approach
is the same kind of object we get here
with that object literal approach.
The advantage now just is
that since we have that blueprint,
we can easily create multiple jobs
by simply repeating this code over and over again,
and we then don't have to manually copy
and paste key-value pairs over and over again,
as we have to when using that object literal notation
because manually copying property names is error prone.
It's easy to add a typo somehow.
If you have a blueprint here
where you locked in the property names once,
and you then just create different instances
of that blueprint, different objects based on that blueprint
by using new and then executing the class like a function,
then you avoid such typos
and you have way less error-prone code.
Of course, using a blueprint really only makes a lot
of sense if you do create multiple versions of that object.
If you just create one object once in your code
to group a couple of values together,
then you probably don't need
to create a blueprint like this.
But it is a concept that can come in handy
if you need multiple objects of the same type,
and it is also something that we'll see later again.
And now you also understand a bit better
what happened when we created a date like this.
But now let's add more logic to our class.