Prototypes
This has been mentioned several times in this tutorial already, but it deserves a repetition: JavaScript is a prototype-based programming language.
If you're new to programming, this won't matter to you, but it can be a bit confusing if you come from one of the more classical, object oriented, class based programming languages like C++, Java or C#. In that case, you may look at this prototype-based alternative as inferior and less powerful, but looks can be deceitful - prototypes are indeed very powerful!
In fact, prototypes are so powerful that the creators of the JavaScript language was able to use it to implement the concept of classes in JavaScript in the Ecmascript version 6 specification. So, classes in JavaScript are actually based on prototypes, but this has been mostly abstracted away, allowing programmers who are more comfortable with the class-based model to use this instead of the prototype model.
But classes in JavaScript are the topic of one of the next chapters in this tutorial - for now, let's talk more about objects and prototypes.
Prototype chain
In JavaScript, all objects that you create is based on a prototype. This might come as a surprise to you, because as we have seen in previous articles, it's very simple to create and use objects and nowhere is the word "prototype" mentioned when doing so. But it's quite easy to spot if you know where to look - just consider this example:
let user =
{
name: "John Doe"
};
console.log(user);
If you run it, and look in the console of your browser you will see something like this:
See that [[Prototype]] property? It clearly illustrates that your custom object inherits, through prototypical inheritance, from the Object object. If you want further proof of this, try this example:
let user =
{
name: "John Doe"
};
alert(user.toString());
We're calling a method called toString(), even though we haven't defined such a method on our object. However, Object does implement this method (as seen from the screenshot of the console above) and our user object inherits it. So, in JavaScript, if we try to access a member of an object and this member can't be found, the member is automatically searched for through the prototype chain.
Shadowing
But even though your object inherits methods like toString(), you are free to override it if you want to. In fact, this is quite normal to do, to make the string version of your object unique and more descriptive of the underlying object. You don't need any special keywords to override a method - just declare the method as you would with any other object method and JavaScript will immediately find it instead of searching the prototype chain:
let user =
{
name: "John Doe",
toString: function() { return "User: " + this.name; }
};
// User: John Doe
alert(user.toString());
This is often referred to as shadowing, when doing it in JavaScript, or overriding in the more class-based programming languages.
Summary
When creating an object in JavaScript, it's automatically based on the Object prototype, from which it inherits properties and methods. You are free to override any inherited behavior, and you can of course create and use your own objects as prototypes as well. In the next article, we'll talk more about the prototype chain and prototypical inheritance.