JS: Introduction to Object Oriented Programming (OOP)
Theory: Prototypes
This lesson will give a brief introduction to the topic of prototypes. It's impossible to say everything about it in one lesson. Not even a whole course is enough. Prototypes are learned only through practice combined with theoretical training. So don't worry if you don't understand everything the first time, it's normal.
Prototypes are the mechanism with the biggest impact on how objects work in JavaScript. They're rarely used directly in code (and usually only in libraries), but knowing them is important for understanding code behavior and debugging. Particularly when working with classes, which we'll cover later in the course. We'll merely go over the fundamentals in this lesson. We have another course listed in the supplementary materials, which will help you understand prototypes in depth.
In JavaScript, each object has a prototype associated with it. A prototype is a regular object stored in a special [[prototype]] service field (this field cannot be directly accessed). It can be extracted like this:
What is it for? To address this topic, we must first understand how JavaScript property calls work. Until now, it was simple: if an object has a property, you can call it and get a value; if there is no property, you get undefined when you access it. That's the truth, but not the whole truth. JavaScript is a little trickier and doesn't just look for a property in the object itself. If no property is defined for an object, JavaScript looks at the prototype and tries to figure out if the prototype has the necessary property. If there is, its value is returned.
In reality, the process is even more complicated. If the property is not found in the prototype, JavaScript looks at the prototype's prototype and so on until it reaches the end of the chain, and it does indeed have an end: the last prototype in the prototype chain is always null. Inheritance is implemented via this mechanism. This topic is beyond the scope of the current lesson.
Even normal JavaScript objects have a prototype:
This is the reason why even empty objects contain properties and methods (remember, properties and methods are in the prototype):
You can access the prototype not only from objects, but also from the prototype property of the constructor that creates those objects:
Now we can answer this question, “where does the prototype come from?” The prototype is the object in the prototype property of the constructor function, not the constructor itself. It's easy enough to test the prototypes by modifying them.
Nothing is stopping you from replacing the value of the getName property in a specific object. This won't affect other objects in any way, since they retrieve getName from the prototype:
Creating properties through a prototype is the proper way to create your abstractions in JavaScript. Any additional abstraction that we add to the code should resemble a constructor and prototype and have the appropriate features.
What is the benefit of this mechanism?
The simplest benefit is that extends the language kernel and libraries without direct access to the source code. Prototypes are an incredibly flexible mechanism that allows you to change anything from anywhere in the program (during runtime). For example, we can add or replace any methods in any objects of the language itself.
Like any other powerful mechanism, prototypes are incredibly dangerous. You can make such a mess that programming becomes a living hell.
But if you use this mechanism wisely, you can get a lot of good things. For example, prototypes are actively used in testing, they help to spoof unwanted method calls that perform HTTP requests. Another popular option is polyfills. This is code that adds features from newer versions to older versions of JavaScrip. Not all of them, of course; only those that appear as properties and methods.
P.S. Now you know why in the documentation all function names are described like that: Number.prototype.toLocaleString().

