The concept of js inheritance
The following two inheritance methods commonly used in js:
Prototype chain inheritance (inheritance between objects)
Classical inheritance (inheritance between constructors)
Since js is not a truly object-oriented language like java, js is object-based and it has no concept of classes. Therefore, if you want to implement inheritance, you can use the prototype prototype mechanism of js or use the apply and call methods to implement it
In an object-oriented language, we use classes to create a custom object. However, everything in js is an object, so what method can be used to create a custom object? This requires the js prototype:
We can simply regard prototype as a template. The newly created custom objects are a copy of this template (prototype) (actually not a copy but a link, but this kind of link is invisible. There is an invisible __Proto__ pointer inside the newly instantiated object, pointing to the prototype object).
js can simulate and implement the functions of classes through constructors and prototypes. In addition, the implementation of js type inheritance is also achieved by relying on prototype chains.
Prototype inheritance and class inheritance
Classical inheritance is the call of a supertype constructor inside the subtype constructor.
Strict class inheritance is not very common, and is generally used in combination:
The code copy is as follows:
function Super(){
this.colors=["red","blue"];
}
function Sub(){
Super.call(this);
}
Prototype inheritance is to create a new object with the help of existing objects and point the prototype of the subclass to the parent class, which is equivalent to adding the prototype chain of the parent class.
Prototype chain inheritance
In order for a child class to inherit the properties of the parent class (including methods), a constructor is first necessary to define. Then, assign a new instance of the parent class to the prototype of the constructor. The code is as follows:
The code copy is as follows:
<script>
function Parent(){
this.name = 'mike';
}
function Child(){
this.age = 12;
}
Child.prototype = new Parent();//Child inherits Parent and forms a chain through the prototype.
var test = new Child();
alert(test.age);
alert(test.name);//Get inherited attributes
//Continue to inherit the prototype chain
function Brother(){ //brother construct
this.weight = 60;
}
Brother.prototype = new Child();//Continue to prototype chain inheritance
var brother = new Brother();
alert(brother.name);//Inherit Parent and Child, mike pops up
alert(brother.age);//Pop 12
</script>
The above prototype chain inheritance is still missing one link, that is Object, and all constructors are inherited from Object. Inheriting Object is automatically completed and does not require manual inheritance by ourselves. So what is their subordinate relationship?
Determine the relationship between prototype and instance
There are two ways to determine the relationship between a prototype and an instance. Operator instanceof and isPrototypeof() methods:
The code copy is as follows:
alert(brother instanceof Object)//true
alert(test instanceof Brother);//false,test is the superclass of brother
alert(brother instance of Child);//true
alert(brother instance of Parent);//true
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 a supertype (parent class, base class, and also) and the inherited function is called a subtype (subclass, derived class). Using prototype inheritance mainly involves two issues:
First, literal rewriting of prototypes will break the relationship, use the prototype of the reference type, and the subtype cannot pass parameters to the supertype.
Pseudo-class solves the problem of reference sharing and supertypes being unable to pass arguments. We can use the "borrow constructor" technology.
Borrowing constructor (classical inheritance)
The code copy is as follows:
<script>
function Parent(age){
this.name = ['mike','jack','smith'];
this.age = age;
}
function Child(age){
Parent.call(this,age);
}
var test = new Child(21);
alert(test.age);//21
alert(test.name);//mike,jack,smith
test.name.push('bill');
alert(test.name);//mike,jack,smith,bill
</script>
Although borrowing constructors solved the two problems just now, without prototypes, there is no way to reuse, so we need a prototype chain + borrow constructor pattern. This pattern is called combination inheritance.
Combination inheritance
The code copy is as follows:
<script>
function Parent(age){
this.name = ['mike','jack','smith'];
this.age = age;
}
Parent.prototype.run = function () {
return this.name + ' are both' + this.age;
};
function Child(age){
Parent.call(this,age);//Object impersonates and passes parameters to supertypes
}
Child.prototype = new Parent();//Prototype chain inheritance
var test = new Child(21);//Writing new Parent(21) is OK
alert(test.run());//mike,jack,smith are both21
</script>
Combination inheritance is a relatively commonly used inheritance method. The idea behind it is to use the prototype chain to implement the inheritance of prototype properties and methods, and to implement the inheritance of instance properties by borrowing constructors. In this way, function multiplexing is achieved by defining methods on the prototype, and ensuring that each instance has its own properties.
Usage of call(): Call a method of an object and replace the current object with another object.
The code copy is as follows:
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
Prototype inheritance
This way of inheriting the creation of new objects based on existing objects without creating custom types is called prototype inheritance
The code copy is as follows:
<script>
function obj(o){
function F(){}
F.prototype = o;
return new F();
}
var box = {
name: 'trigkit4',
arr : ['brother','sister','baba']
};
var b1 = obj(box);
alert(b1.name);//trigkit4
b1.name = 'mike';
alert(b1.name);//mike
alert(b1.arr);//brother, sister,baba
b1.arr.push('parents');
alert(b1.arr);//brother, sister,baba,parents
var b2 = obj(box);
alert(b2.name);//trigkit4
alert(b2.arr);//brother, sister,baba,parents
</script>
Prototype inheritance first creates a temporary constructor inside the obj() function, then uses the passed object as the prototype of the constructor, and finally returns a new instance of this temporary type.
Parasitic inheritance
This inheritance method combines the prototype + factory model, with the purpose of encapsulation creation process.
The code copy is as follows:
<script>
function create(o){
var f= obj(o);
f.run = function () {
return this.arr;// Similarly, references will be shared
};
return f;
}
</script>
Small problems with combination inheritance
Combination inheritance is the most commonly used inheritance mode in js, but the supertype of combined inheritance will be called twice during use; once is when creating a subtype, and the other is inside the subtype constructor.
The code copy is as follows:
<script>
function Parent(name){
this.name = name;
this.arr = ['Brother','Sister','Parents'];
}
Parent.prototype.run = function () {
return this.name;
};
function Child(name,age){
Parent.call(this,age);//The second call
this.age = age;
}
Child.prototype = new Parent();//The first call
</script>
The above code is the previous combination inheritance, so parasitic combination inheritance solves the problem of two calls.
Parasitic combination inheritance
The code copy is as follows:
<script>
function obj(o){
function F(){}
F.prototype = o;
return new F();
}
function create(parent,test){
var f = obj(parent.prototype);//Create an object
f.constructor = test;//Enhanced object
}
function Parent(name){
this.name = name;
this.arr = ['brother','sister','parents'];
}
Parent.prototype.run = function () {
return this.name;
};
function Child(name,age){
Parent.call(this,name);
this.age =age;
}
inheritPrototype(Parent,Child);//Inheritization is realized through here
var test = new Child('trigkit4',21);
test.arr.push('nephew');
alert(test.arr);//
alert(test.run());//Only the method is shared
var test2 = new Child('jack',22);
alert(test2.arr);//Solve the citation problem
</script>
call and apply
The global functions apply and call can be used to change the pointing of this in the function, as follows:
The code copy is as follows:
// Define a global function
function foo() {
console.log(this.fruit);
}
// Define a global variable
var fruit = "apple";
// Customize an object
var pack = {
fruit: "orange"
};
// Equivalent to window.foo();
foo.apply(window); // "apple", this is equal to window
// This === pack in foo
foo.apply(pack); // "orange"