-: In this lecture we will take closer look
at objects in JavaScript.
We will talk about object-oriented programming
in general, inheritance, and how JavaScript handles
objects and inheritance through prototypes.
This is probably one of the most important
lectures in this course if you really want
to understand JavaScript.
So there's a saying in JavaScript which says that,
"Everything is an object."
And while this is almost correct,
it is not 100 percent correct though.
Because in JavaScript, we have two big types
of values, primitives and objects.
And primitives are all the values that have one
of the data types that we talked about
in the intro lectures.
So numbers, strings, booleans, undefined and null values,
all of these are primitives,
and everything else are objects.
And that's why in JavaScript we say
that everything is an object.
And in fact, even simple things like
functions, arrays, or dates are all objects in JavaScript,
and that's because in JavaScript objects are not
just for storing a bunch of data,
like we have been doing,
but for really complex things under the surface.
So we have been using objects all along,
just without knowing it.
So always remember that almost everything
is an object in JavaScript,
because it's one of the fundamental things
that makes JavaScript so unique and different
from other popular programming languages.
Alright so now that we know how important
objects are in JavaScript,
let's look at object-oriented programming.
So, in very simple terms object-oriented programming
makes heavy use of objects, properties, and methods,
and these objects interact with one another
to form complex applications.
We use objects to store data, structure our code,
and keep our code clean.
So far, we have only created
simple objects holding some data.
I remember the John object from the intro lectures
and if we had created other persons back then
we would simply have written them one-by-one
like Mark, Jane et cetera, right?
But there is a better way,
imagine something like a blueprint
from which we can generate as many objects as we want,
and we can do that in JavaScript.
And right here is an example of that.
This is a special Person object
that we can basically use as a blueprint
to create a lot of Person objects.
In other programming languages,
this is many times called a class,
but in JavaScript we like to call it
a constructor or prototype.
So based on this constructor,
we can create as many instances as we want.
So here are our Jane, Mark, and John objects once again,
but these were created from the Person constructor.
So they are effectively Person instances,
and now their name, year of birth,
and job variables are defined,
and they all have access to the calculateAge method.
So again, the constructor acts like a blueprint
and is used to create instances,
which of course are also objects.
We will, of course, do all of this with code
over the next lectures,
this is just to give you a very brief overview.
And now let's take this even
one step further, with inheritance.
In simple terms, inheritance is when one object
is based on another object.
It's when one object gets access
to another object's properties and methods.
So, very simple.
Back to our persons example, imagine that you also
wanted to have an athlete constructor,
besides the person constructor,
with a couple of different properties and methods.
Now, an athlete is also a person, right?
There are just some particular properties
and methods for an athlete, like for example
how many participations in Olympics they have
or how many medals they have won.
So when we define the blueprint, so the constructor,
for an athlete, then why repeat the same stuff
that we have in our Person constructor?
An athlete also has a name, year of birth, and job, right?
So what we can do is to use inheritance.
We make the Athlete object inherit the properties
and methods from the Person object,
so then the Athlete not only has access
to its own properties and methods
but also the ones from the Person object.
Really cool, right?
This allows us to write less code
and make more logical programs.
So this is a broad overview
of how inheritance works in theory,
and in all programming languages
that have object-oriented futures.
So let's now see how JavaScript in particular
handles inheritance with our Person and John examples.
JavaScript is a prototype-based language,
which means that inheritance works by using
something called prototypes.
In practice, it means that each and every JavaScript
object has a prototype property
which makes inheritance possible in JavaScript.
So again, inheritance is made possible
through the prototype property that every object has.
Now all of this may look a bit confusing
at first sight, but don't worry,
because we will do everything in code later as well.
But before doing that, it's super important the we get
at least a visual overview of what happens
behind the scenes.
Alright, now, how does inheritance actually work?
To better understand this, let's go back
to our Person example, where the Person object
is the constructor and John is one of the instances.
Now, if we want John to inherit a method
or a property from the Person object
we have to add that method or property
to the Person's prototype property,
just like we see it here.
So in this example, we have the calculateAge
method in the Person's prototype property
and therefore john inherits the method,
and can then call it.
And any other object created by the Person constructor
would inherit this method as well.
So, again, the prototype property of an object
is where we put methods and properties
that we want other objects to inherit.
What is really important to note here
is that the Person prototype is not
the prototype of the person itself,
but of all instances that I created
through the Person blueprint,
like, for example, john.
So in other words, the Person's prototype property
is the prototype of John.
And that's not even all,
because the Person object itself
is an instance of an even bigger constructor,
which is the Object object.
Yeah, that sounds a bit crazy,
but this is actually how it works.
Each and every object that we ever create
is an instance of the Object constructor
which has a bunch of methods in its prototype property.
And, as you can guess, the Person object inherits
these methods and can call them.
Plus, the john object also inherits these methods
and can also use them.
And, with that, we have actually
explained the prototype chain.
So, the prototype chain is what makes
all this inheritance possible,
and here is how it works.
When we try to access a certain method,
or property on an object, JavaScript will
first try to find that method on that exact object.
But if it cannot find it, it will look
in the object's prototype, which is the prototype
property of its parent.
So it moves up in the prototype chain.
If the method is still not there,
this continues until there is no more
prototype to look at, which is null.
Null is the only one that has no prototype,
and is therefore the final link in the prototype chain.
And in this case, undefined is returned.
This is the reason why, for example,
the john object could call the hasOwnProperty method
that is stored in the Object Prototype property.
And since this is all so crazy important
I even took the time to write down a summary for you
about the most important things about prototypes,
so that you can copy it if you want.
So here it goes:
Every JavaScript object has a prototype property,
which makes inheritance possible in JavaScript.
The prototype property of an object
is where we put methods and properties
that we want other objects to inherit.
The Constructor's prototype property
is not the prototype of the Constructor itself,
but it's the prototype of all instances
that are created through it.
When a certain method, or property, is called,
the search starts in the object itself,
and if it cannot be found there,
the search moves up on to the object's prototype.
This continues until the method is found.
And this is the prototype chain.
Alright, so this is it about objects, inheritance
and prototypes in JavaScript.
I promise that we'll now finally go back to our code.