As an object-oriented language (JS is object-based), it is essential to implement inheritance, but since there is no concept of class itself, it will not implement inheritance through classes like a real object-oriented programming language, but can implement inheritance through other methods. There are many ways to implement inheritance, and the following are just a few of them.
1. Prototype chain inheritance
function Person() { //The inherited function is called a supertype (parent class, base class) this.name='mumu'; this.age='18'; } Person.prototype.name='susu';//When the attribute name is the same, you need to be nearest, search in the instance first, but then go to the prototype to find function Worker() { //The inherited function is called a subtype (subclass, derived class) this.job='student'; } Worker.prototype=new Person();//Inherited through the prototype chain, the object instance instantiated by the supertype is assigned to the prototype attribute of the subclass var p2=new Worker(); console.log(p2.name); console.log(p2 instanceof Object);//ture All constructors are inherited from ObjectThe key to implementing inheritance above is: Worker.prototype=new Person(); Make the Worker prototype an instance of Person and inherit it through the prototype chain.
Note: When using prototype chains to implement inheritance, you cannot use object literals to create prototype methods, because this will interrupt the relationship and rewrite the prototype chain.
Prototype chain inheritance problem:
1. There is a reference sharing problem, and they still share the same space, and the subclass will affect the parent class.
function Person() { this.bodys=['eye','foot']; } function Worker(){ } Worker.prototype=new Person(); var p1=new Worker(); p1.bodys.push('hand'); var p2=new Worker(); console.log(p1.bodys); console.log(p2.bodys);2. When creating instances of subtypes, parameters cannot be passed in supertype constructors.
So how to solve the two problems of prototype chain? Then continue to look at the inheritance method below ~
2. Borrowing constructor inheritance (also called object impersonation, forged object or classic inheritance)
function Person(name,age){ this.name=name; this.age=age; this.bodys=['eye','foot']; } Person.prototype.showName=function(){ console.log(this.name); } function Worker(name,age,job){ Person.call(this,name,age); this.job=job;//Subclass add attributes} var p1=new Worker('mumu','18','student'); p1.bodys.push('hand') ; var p2=new Worker(); console.log(p1.name); console.log(p2.bodys); console.log(p1.showName());A brief analysis of the above principle of using borrowed constructors: Person.call(this,name,age); This code calls the parent constructor, inherits the parent attribute, and uses the call method to call the Person constructor to change this when the function is executed. Here, this-> new is a Worker object constructor disguised method: pass the Worker to the Person above.
When the reference type is placed in the constructor, it will not be shared, so p2 is not affected.
Borrowing the constructor inheritance method here solves the problem that the prototype chain cannot pass parameters and share reference types.
Tips: call() and apply() methods can change the scope of function execution, in short, change the content pointed to by this function.
Both call() and apply() accept two parameters: the first is the scope of the function running in it, and the other is the passed parameter.
The difference between call and apply is the difference in parameters.
The parameters in the call must be enumerated one by one.
The parameters in apply must be arrays or arguments objects
So the question is: Why is the result of p1.showName() wrong? ----Because the inheritance method of borrowing constructors can only inherit attributes and methods in the constructor. Here we also find a problem of borrowing constructors.
Note: Since we put all methods in the constructor, every time we instantiate, we will allocate memory space to waste resources, so we usually put methods in the prototype and attributes in the constructor.
Borrowing constructor inheritance problem:
Because borrowing a constructor can only inherit the properties and methods in the constructor, the methods defined in the supertype prototype are invisible to the subclass, so it is equivalent to having no prototype. As a result, all methods can only be defined in the constructor, so there is no function multiplexing.
So how to solve the problem caused by borrowing constructors? Then it depends on the following inheritance method
3. Combination inheritance (pseudo-classic inheritance)
function Person(name,age){ this.name=name; this.age=age; } Person.prototype.showName=function(){ console.log(this.name); } function Worker(name,age,job){ Person.call(this,name,age);//Borrow constructor this.job=job; } Worker.prototype=new Person();//Prototype chain inheritance var p1=new Worker('mumu','18','Student'); console.log(p1.age); p1.showName();Combination inheritance: Combining the prototype chain with the borrowed constructor.
Idea: By using the prototype chain to implement the inheritance of attributes and methods on the prototype, and by borrowing the constructor to implement the inheritance of instance attributes
The above example Person.call(this,name,age); borrows the constructor to inherit attributes
Worker.prototype=new Person();The prototype chain inherits the method, avoids the shortcomings of the two, combines their advantages, and becomes the most commonly used inheritance model.
Combination inheritance issues:
The supertype constructor is called twice, once when creating a subtype prototype and the other time inside the subtype constructor.
To solve this problem, we must use parasitic combination inheritance.
4. Prototype inheritance
function object(proto) { function F() {} F.prototype = proto; return new F(); } var person = { name: 'mumu', friends: ['xiaxia', 'susu'] }; var anotherPerson = object(person); anotherPerson.friends.push('wen'); var yetAnotherPerson = object(person); anotherPerson.friends.push('tian'); console.log(person.friends);//["xiaxia", "susu", "wen", "tian"]console.log(anotherPerson.__proto__)//Object {name: "mumu", friends: Array[4]}A brief analysis: function object(proto) is a temporary relay function, the parameter proto in it represents an object to be passed in. The F() constructor is a temporary newly created object, which is used to store the passed object. F.prototype = proto; assign the object instance to the prototype object of the F constructor, and finally return the object instance of the passed object. Prototype inheritance or share attributes of reference types.
5. Parasitic inheritance
//Temporary transit function object(proto) { function F() {} F.prototype = proto; return new F(); } //Parasite function create(proto){ var f=object(proto); f.love=function(){ return this.name; } return f; } var person = { name: 'mumu', friends: ['xiaxia', 'susu'] }; var anotherPerson = create(person); console.log(anotherPerson.love()); Parasitic combination inheritance6. Parasitic combination inheritance
function object(proto) { function F() {} F.prototype = proto; return new F(); } //Parasite function function create(Person,Worker){ var f=object(Person.prototype);//Create object f.constructor=Worker;//Adjust the prototype construction pointer and enhance the object Worker.prototype=f;//Specify the object} function Person(name,age){ this.name=name; this.age=age; } Person.prototype.showName=function(){ console.log(this.name); } function Worker(name,age,job){ Person.call(this,name,age); this.job=job; } create(Person,Worker);//Parasite combination inheritance var p1=new Person('mumu','18','Student'); p1.showName();This method is also the most perfect and ideal way to implement inheritance methods now.
The above JavaScript inheritance learning notes [must read for beginners] is all the content shared by the editor. I hope it can give you a reference and I hope you can support Wulin.com more.