A lot of fancy words there, so let’s break that down. When we say that something is syntactic sugar, we mean that it serves as a nicer, cleaner, possibly easier to read way of doing something.
this keyword to dynamically set the value of
Line six is where we give this
PersonOldWay constructor function the
sayHello function. Notice that, in order to do so, we access the
PersonOldWay prototype property.
Under the hood, we are actually doing the exact same thing in the first code snippet. Remember that the first code snippet is just a prettier version of the second code snippet. It doesn’t actually achieve anything that couldn’t be done before.
Inside of our
Person.prototype, we see both the
constructor function and the
sayHello function that we defined. The prototype property will continue to expand as we add more and more methods to our class, but you also likely noticed that
__proto__ points to
Object. What exactly is that?
__proto__ tells us that
Person inherits from
Object.prototype. If we look at
Object.prototype, we can see various methods defined there — the
toString method for example. We can call the
toString method on the
Person class, because
Person inherits these methods from further up the prototype chain.
This is a good thing, as it allows us to be more memory efficient by simply writing a method once, and then letting objects that need it, inherit it.
__proto__, in our case
Person.prototype, to see if the property exists there.
It will repeat this process until it either finds it, or it reaches the end of the chain and returns null.
If you are familiar with a language that uses classical inheritance (like Java or Ruby), some of this may sound familiar. Languages that use classical inheritance also have a way of reusing code, so what exactly is the difference?
In JavasScript, everything is just an object inheriting from another object. There are no blueprints, but rather prototypes. A prototype itself is a working piece of code. I can give functionality directly to the
Person function. I can do this at any point after defining the function. What exactly do I mean by a working piece of code?
Here, a new function call
personFunction was make directly on
Person. It doesn’t do anything special; it just returns a string. The object
adam inherits from
Person, which is to say that
Notice though, that we cannot simply call
adam.personFunction(), because that function does not exist on the
adam inheritance chain. Rather, it exists directly on the constructor.
Person can do more than just define how
adam will behave, meaning it can do work.
Above, we define a simple Java class called
Dog and give it a three-argument constructor. This class will define how each instance of
Dog will look. Every instance of
Dog will have two strings corresponding to name and breed, and one integer corresponding to its age. The class itself does not do any work.
In classical inheritance languages, the class functions as a blueprint for creating objects (instances of the class). The class itself serves no purpose, other than to define the methods and attributes that its instances will inherit.
In other words, you can’t do anything practical with a Java class, other than define how its instances will behave. Classes in Java will inherit from other classes, provided the child has a potentially larger, more robust blueprint.
However, it doesn’t matter how long the inheritance chain is, the class itself will never be more than just a blueprint.