The concept of js inheritance
The following two inheritance methods are commonly used in js:
Prototype chain inheritance (inheritance between objects)
Class inheritance (inheritance between constructors)
Since js is not a truly object-oriented language like java, js is based on objects and has no concept of classes. Therefore, if you want to implement inheritance, you can use the prototype mechanism of js or the apply and call methods
In object-oriented languages, we use classes to create a custom object. However, everything in js is an object, so how to create a custom object? This requires the use of js prototype:
We can simply think of prototype as a template. The newly created custom objects are all copies of this template (prototype) (actually not copies but links, but this link is invisible. New There is an invisible __Proto__ pointer inside the instantiated object, pointing to the prototype object).
JS can simulate the functions of classes through constructors and prototypes. In addition, the implementation of js class inheritance also relies on the prototype chain.
Prototypal inheritance and class inheritance
Classic inheritance is calling the constructor of the supertype inside the constructor of the subtype.
Strict class inheritance is not very common, and is usually used in combination:
function Sub(){
Super.call(this);
}
Prototype chain inheritance
In order for the subclass to inherit the attributes (including methods) of the parent class, you first need to define a constructor. Then, assign the new instance of the parent class to the constructor's prototype. The code is as follows:
The above prototype chain inheritance is missing a link, that is Object. All constructors inherit from Object. Inheriting Object is done automatically and does not require us to inherit manually. So what is their affiliation?
Determine the relationship between prototype and instance
The relationship between prototypes and instances can be determined in two ways. Operator instanceof and isPrototypeof() methods:
As long as it is a prototype that appears in the prototype chain, it can be said to be the prototype of the instance derived from the prototype chain. Therefore, the isPrototypeof() method will also return true
In js, the inherited function is called the super type (parent class, base class is also acceptable), and the inherited function is called the subtype (subclass, derived class). There are two main problems with using prototypal inheritance:
First, literal overriding of the prototype will break the relationship and use the prototype of the reference type, and the subtype cannot pass parameters to the supertype.
Pseudo classes solve the problem of reference sharing and the inability to pass parameters of super types. We can use the "borrowed constructor" technology
Borrow constructor (class inheritance)
Combined inheritance
Combined inheritance is a commonly used inheritance method. The idea behind it is to use the prototype chain to inherit prototype properties and methods, and to borrow constructors to inherit instance properties. In this way, function reuse is achieved by defining methods on the prototype, and each instance is guaranteed to have its own attributes.
Usage of call(): Call a method of an object and replace the current object with another object.
This kind of inheritance uses prototypes to create new objects based on existing objects without creating custom types. It is called prototypal inheritance
Prototypal inheritance first creates a temporary constructor inside the obj() function, then uses the incoming object as the prototype of this constructor, and finally returns a new instance of this temporary type.
Parasitic inheritance
This inheritance method combines the prototype factory pattern with the purpose of encapsulating the creation process.
Small problems with combined inheritance
Combined inheritance is the most commonly used inheritance pattern in js, but the supertype of combined inheritance will be called twice during use; once when creating the subtype, and the other time inside the subtype constructor
The above code is the previous combination inheritance, so the parasitic combination inheritance solves the problem of two calls.
Parasitic Combinatorial Inheritance
call and apply
The global functions apply and call can be used to change the pointer of this in the function, as follows:
// Define a global variable
var fruit = "apple";
// Customize an object
var pack = {
fruit: "orange"
};
// Equivalent to window.foo();
foo.apply(window); // "apple", at this time this is equal to window
//This in foo at this time === pack
foo.apply(pack); // "orange"