This article summarizes common inheritance patterns of JavaScript. Share it for your reference, as follows:
There is no concept of classes in traditional object-oriented languages in JavaScript, but it implements a special inheritance mechanism.
(You first need to know the prototype)
Let’s first talk about the first inheritance method, prototype chain inheritance.
1. Prototype chain inheritance
The so-called prototype chain inheritance means that an instance of the parent class is used as the prototype of the child class.
Right now :
parentInstance = new Parent(); = parentInstance;
In this way, when creating an instance of a subclass, the subclass instance's__proto__Point to the instance of the parent class (that is, the prototype property of the subclass constructor at this time), and the instance of the parent class__proto__also point to the parent class constructorprototypeproperty. Borrowing this method creates a prototype chain.
Since there are the following ways to search for variables in instances in JavaScript:
- Looking for variable names in the current instance
- Find in the prototype pointed to by the current instance
Assume that there is the following inheritance relationship in the prototype chain:
grandparent(there is a method) -> parent -> child
When the method saysHello is called in child's instance child_ming, first search for saysHello in child_ming (that is, only defined in child_ming, not all instances), and it is not found, and then it starts searching for the prototype it points to, that is, the instance of parent. There is also no such method in the parent instance, start searching for the parent prototype, that is, the instance of grandparent. In the grandparent instance, it still was not found. Search for the grandparent prototype and find the method.
It can be seen that inheritance is realized.
As with the problem encountered when creating objects using prototype, if you use the prototype chain to inherit completely, some properties that require inheritance but do not need to be shared among different instances will become inconvenient to implement.
Let’s talk about inheritance implemented by borrowing constructors.
2. Borrowing constructors to achieve inheritance
The so-called borrowing constructor to implement inheritance, that is, borrowing the constructor of the parent class in the constructor of the subclass to use, in order to generate the properties of the parent class in the subclass.
Look at the following code:
function Parent(color){ = color; = function(){ alert(); }; } function Child(color,size){ (this,color); = size; }
This is a simple inheritance of a borrowed constructor.
By using the constructor of the parent class, the same attribute of different instances of the same constructor can have different values. Solved the disadvantage of attribute sharing in prototype chain inheritance.
However, like the problems encountered when creating objects using constructors, methods generated by constructors face the problem of repeated definitions. Different instances under the same class have their own methods, and generally speaking, methods need to be reused, and there is no need to let them have their own methods.
Using combination inheritance can solve this problem.
3. Combination inheritance (prototype chain and borrow constructor)
Since the prototype chain can realize attribute sharing and borrowing constructors can realize the private ownership of attribute values, you might as well combine them, which forms a combination inheritance.
The so-called combination inheritance is actually inheriting with a prototype chain and inheriting with a borrowed constructor.
Look at the following code:
function Parent(color){ = color; } = function(){ alert(); }; function Child(color,size){ (this,color); //Borrow the constructor to inherit attributes = size; } //The following attribute 'green' has no effect, here we need to use the prototype inheritance method = new Parent('green'); var child_demo = new Child('red',200);
First, think about these two questions. How many color attributes does it generate when creating a child instance? In the code, both 'red' is defined and 'green' is defined.child_demo.getColor()
When, which one will alert?
Let’s look at the first question first. Since the parent class constructor is borrowed from the subclass constructor, the color attribute will inevitably be generated once when creating a subclass instance. But don't forget that when inheriting the method, we let the prototype of the subclass constructor point to an instance of the parent class. When creating this parent class instance, we must generate the color attribute (i.e. at 'green' above), and this attribute is completely unnecessary. So a total of two color attributes were generated, one was useful and the other was useless.
Let’s look at the second question. As long as you can understand the meaning of this, you can know:
child_demo.getColor() // 'red' () //'green'
Combination inheritance combines the advantages of the first two inheritance methods, but it also has its own disadvantages. From generating two color properties, we can know that the Parent constructor was called twice during the inheritance process, which will cause the execution completion speed and affect the efficiency. However, the flaws do not conceal the merits, and this inheritance method has become the most commonly used inheritance model in JavaScript.
4. Prototype inheritance
Prototype inheritance is inheriting from existing objects and creating new objects based on existing objects.
Look at the following code:
var obj = { color: 'red', getColor: function(){ alert(); }, }; //getChild(obj) returns an instance of __proto__ pointing to objfunction getChild(obj){ function func(){} = obj; return new func(); } var child_demo = getChild(obj);
This inheritance method has similarities and differences with the prototype chain inheritance method.
Similarities: They all implement inheritance by changing the prototype properties of the subclass constructor, and the inherited properties have the characteristics of sharing different instances.
The difference: The prototype of the subclass constructor in the prototype chain inheritance is an instance of the parent class (the things we really need to inherit may exist in the prototype of the parent class constructor, or may exist in the parent class instance directly pointed to), while the prototype of the subclass constructor in the prototype inheritance is an existing object, which can be said to be the parent class directly.
5. Parasitic inheritance
Parasitic inheritance can be said to be a variant of prototype inheritance. It encapsulates prototype inheritance so that creating subclass instances depends on only one function.
Look at the following code:
var obj = { color: 'red', getColor: function(){ alert(); }, }; function getChild(obj){ function func(){} = obj; return new func(); } /*--------------------------*/ function betterGetChild(obj,size){ var temp_obj = getChild(obj); temp_obj.size = size; temp_obj.getSize = function(){ return ; }; return temp_obj; } var demo = betterGetChild(obj,200);
6. Parasitic combination inheritance
Parasitic combination is an application of combination inheritance plus prototype inheritance. Since the prototype of the subclass constructor in combination inheritance points to an instance of the parent class rather than the prototype of the parent class constructor, an additional call to the parent class constructor is caused when setting the prototype of the subclass constructor. Therefore, in parasitic combination inheritance, the idea of prototype inheritance is borrowed, and the prototype of the parent class constructor is regarded as an existing object, so that the prototype of the subclass constructor directly points to it.
Look at the following code:
function getChild(obj){ function func(){} = obj; return new func(); //Calling the constructor} /*--------------------------*/ function Parent(color){ = color; } = function(){ alert(); }; function Child(color,size){ (this,color); //Calling the constructor = size; } //Point directly to an instance pointed to by __proto__ = getChild(); = function(){ alert(); };
In fact, strictly speaking, this method also calls the constructor twice, but one of the constructor calls is a call to an empty function, rather than calling the constructor of the parent class both times.
In combination inheritance, the child class's prototype actually stores the properties that are not defined in the prototype (because the child class constructor's prototype is an instance of the parent class), but the child class constructor borrows the parent class constructor to generate properties that cover those properties in the prototype in the current instance. However, in parasitic combination inheritance, no redundant data is generated at all.
It is generally believed that combination inheritance is the ideal method of inheritance when parasitic.
For more information about JavaScript, you can also view the topic of this site: "JavaScript object-oriented tutorial》、《Summary of JavaScript Errors and Debugging Skills》、《Summary of JavaScript data structure and algorithm techniques》、《JavaScript traversal algorithm and skills summary"and"Summary of JavaScript mathematical operations usage》
I hope this article will be helpful to everyone's JavaScript programming.