There are many examples of prototype inheritance in the wild. Notably, jQuery uses it. Each time you make a jQuery selection, you use the delegate prototype to inherit jQuery methods. It is also widely used in various web applications, including the Abode Creative Cloud platform, many products from Yahoo, etc.
In fact, every implementation of classical inheritance in JavaScript actually uses prototype inheritance to simulate classical inheritance - it is necessary only as a convenience for programmers who are more familiar with classical than prototype inheritance. Prototype inheritance is so flexible that it is trivial to imitate features of classical inheritance using prototype inheritance. The converse is not true.
Prototype inheritance simply means that an object is inherited directly from another object. Here is an example:
var switchProto = { isOn: function isOn() { return this.state; }, toggle: function toggle() { this.state = !this.state; return this; }, state: false }, switch1 = Object.create(switchProto), switch2 = Object.create(switchProto);
Usually, the factory function is used to call Object.create() to make creating the object more convenient.
There are many problems with classical inheritance that do not exist with prototype inheritance, for example:
Classic inheritance
Tight coupling. Inheritance is the narrowest connection available in OO design. Descendant levels have a deep knowledge of their ancestral classes.
Rigid hierarchies (aka duplication as needed). Single parent hierarchies rarely describe all possible use cases. After all, all hierarchies are “wrong” for new uses — a problem that requires code duplication.
Multiple inheritance is complicated. It is often desirable to inherit from multiple parents. This process is overly complex, and its implementation is incompatible with the single inheritance process, which makes it difficult to read and understand.
Fragile architecture. Because of the tight connection, it is often difficult to reorganize a class with an “incorrect” design, since many existing functions depend on the existing design.
Gorilla / Banana challenge. Often there are parts of the parent that you do not want to inherit. The subclass allows you to override the properties of the parent, but does not allow you to choose which properties you want to inherit.
Prototype inheritance
To understand how prototype inheritance solves these problems, you must first understand that there are two different types of prototype inheritance. JavaScript supports both:
Delegation. If the property is not found in the instance, it runs on the instance of the instance instance. This allows you to distribute methods among many cases, providing you with a free fly template.
concatenation. The ability to dynamically add properties to an object allows you to freely copy any properties from one object to another, all together or selectively.
You can combine both forms of prototype inheritance to achieve a very flexible code reuse system. In fact, it is so flexible that it is trivial to implement classical inheritance with prototypes. The converse is not true.
Prototype inheritance allows you to use most of the important functions that you will find in classical languages. In JavaScript, the close and factory functions allow you to implement a private state, and functional inheritance can be easily combined with prototypes to add mixes that maintain data privacy.
Some advantages of prototype inheritance:
Free communication. An instance never needs a direct reference to the parent class or prototype. It is possible to keep a reference to the prototype of the object, but it is not recommended, because it will contribute to tight communication in the hierarchy of objects - one of the biggest errors of classical inheritance.
Flat hierarchies. This is trivial with the OO prototype to keep inheritance hierarchies flat - using concatenation and delegation, you can have one level of delegation of objects and one instance without references to parent classes.
Trivial multiple inheritance. Inheriting from multiple ancestors is as simple as combining the properties of several prototypes using concatenation to create a new object or a new delegate for a new object.
Flexible architecture. Since you can selectively inherit from the OO prototype, you don’t have to worry about the “wrong design” problem. A new class can inherit any combination of properties from any combination of source objects. Due to the simple alignment of the hierarchy, a change in one place does not necessarily cause ripples in the long chain of descendants.
No more gorillas. Selective inheritance eliminates the problem of gorilla banana.
I do not know what the advantage of classical inheritance over prototype inheritance. If anyone knows about anyone, please enlighten me.