7 ways to achieve a deep understanding of JavaScript inheritance

1. prototype chain to inherit

Core: the instance of the parent class as a prototype subclass

First, to know the relationship between the constructor and prototype examples: constructor has a prototype object, the prototype object contains a pointer pointing to the constructor, the instance contains a pointer to the prototype object.

function Father () {
     the this .name = 'name of the parent class' ; 
}    
Father.prototype.getFatherName = function () { 
    the console.log ( ' parent class' ); 
} 

function Son () {
     the this .name = ' name of the subclass' ; 
} 
// If at this time there are son prototype object methods or properties, the following Son.prototype = new Father (), since the prototype redirection, methods and properties on the prototype will be lost 
Son.prototype.getAge = function () { 
    the console.log ( 'age subclass' ) 
} 

Son.prototype = new new father (); // core: create an instance of the parent class, instance and assigned to the prototype subclass 

Son.prototype. getSonName= Function () { 
    the console.log ( 'Method subclass' ); 
} 

var Son = new new Son (); 
son.getFatherName (); // parent class 
. Son.prototype .__ proto __ getFatherName = function () { @ drawback: if there are multiple instances of the parent class prototype, will affect each 
    console.log ( 'subclass method of changing the parent class' ); 
} 
son.getFatherName (); // subclasses of the parent class change

Disadvantages:

 
  
  1. Use this parent declared properties (public attributes and private attributes) is shared by all instances of reference data type operations affect each other between the plurality of instances.

  2. When you create a subclass instance, you can not pass parameters to the parent class constructor.

 
  

2. borrow constructor inherited (Call) #

 
  

Core: using the parent class constructor subclass instance be enhanced, i.e., the parent class instance attributes copy subclasses

function Father(name, age){
    this.name = name;
    this.age = age;
}  
Father.prototype.getFatherName = function(){
    console.log('父类的方法');
}

function Son(name, age, job){
    Father.call(this,name, age); // 继承自Father
    this.job = job;
}
var son = new Son('jacky', 22, '前端开发');
//son.getFatherName(); // Uncaught TypeError: son.getFatherName is not a function

 

advantage:

  1. You can pass parameters to the parent, but also solves the prototype chain inheritance: the parent class properties declared using this property will be shared among all instances of the problem.

Disadvantages:

  1. Only inherit the parent class declared by this property / method, can not inherit properties / methods on the parent class prototype.
  2. Every instance of a subclass of parent class function must be executed again declare this in the parent class defined, so the parent class method can not be reused.

3. The combination of inheritance #

Core: combination of the two methods, inheritance of methods and properties of the prototype prototype chain, using techniques borrowed constructor instance attribute inheritance.

function Father (name, Age) {
     the this .name = name;
     the this .age = Age;
     the this .sex = 'man' ; 
} 
Father.prototype.getFatherName = function () { 
    the console.log ( 'parent process' ) 
} 

function son (name, Age, Job) { 
    Father.call ( the this , name, Age); // second call: creating subtypes instance when 
    the this .job = Job; 
} 
Son.prototype = new new Father () ; // first call: set subtype prototype instance when 
Son.prototype.constructor = son; //refers back to their prototype constructor 

var Son = new new Son ( 'Jacky', 22 is, 'front-end development' ); 
son.getFatherName (); 
the console.log (Son)

advantage:

  1. Can inherit the properties of the parent class prototype, parameters can be transferred, reusable.
  2. Constructors properties of each new class object instance is introduced private.

Disadvantages:

  1. Two calls to the parent function (new fatherFn () and fatherFn.call (this)), cause some performance loss.
  2. When creating an object subclass instance, there is a problem that the prototype will be the same two properties / methods.

expand:

constructor role #

Return to create an instance of the Object constructor references.

When we only instance of an object has no constructor references: In some scenes, we have gone through several rounds of import and export objects for instance, we do not know from which the function is to construct an example out or track constructors instance, is more difficult. (It is mainly to prevent one case wrong, is that you explicitly have to use the constructor for example, I do not know what function instance is instantiated out, but I want a clone, then you can do -> instance.constructor) this time may be obtained by reference to the constructor of the object instance constructor property

let instance = new sonFn () // instantiable subclass 
Export instance; 
// + export import multiple rounds, resulting in very cumbersome sonFn track, or do not want to re-introduced in the file sonFn 
let fn = instance.constructor
 

So every time rewrite function prototype constructor should correct that point, in order to maintain the consistency of read constructor points

4. Prototype Formula inherited (the Object.create ()) #

Core: the use of a null object as an intermediary, directly assign an object to an empty prototype object constructor, and then return to the calling function, this function becomes free to add a property or an instance of an object.

 
  
/ * Object.create () implementation of the principle * / 
// CLONEOBJECT () to perform a shallow copy, the constructor F prototype passed directly to the object to which the incoming object. 
function CLONEOBJECT (obj) {
   function F. () {} 
  F.prototype = obj; // the incoming object obj passed as a function of empty the prototype 
  return  new new F. (); // The prototype of this object is inherited object, prototype chain lookup may get object attributes inherited 
} 

var Father = { 
    name: 'Jacky' , 
    Age: 22 is , 
    courses: [ 'front end' ] 
} 

// var = SON1 the Object.create (Father); // the same effect 
var = SON1 CLONEOBJECT (Father); 
son1.courses.push ('Rear' ); 

var son2 = CLONEOBJECT (Father); 
son2.courses.push ( 'full stack' ); 

the console.log (father.courses); //   [ "front end", "rear", "full-stack "]
 
  

advantage:

New object derived from existing objects do not need to create a custom type

Disadvantages:

Like the prototype chain to inherit. Multiple instances of the shared object's properties to be inherited, there may be tampered with; can not pass parameters.

5. Parasitic inheritance #

Core: Formula inheritance to the prototype, the only function to create a process for packaging succession, the function to do some form within the augmented object (added some new methods and properties), and finally returns the object.

Use Scenario: enhancing specifically targeted to do some fixed way.

function createAnother (obj) {
     var clone = the Object.create (obj); 
    clone.skill = function () {   // some way to enhance this object 
        the console.log ( 'RUN' ); 
    }; 
    return clone; 
} 

var = Animal { 
    EAT: 'Food' , 
    Drink: 'Water' 
} 

var Dog = createAnother (Animal); 
dog.skill ();

 

Advantages: not created custom type, because it is only a set of specific properties increased shell / method returns the object, in order to achieve the purpose of enhanced objects

Disadvantages:

Inherited, with the prototype: Prototype inheritance chain multiple instances of the same point of reference type attribute, there may be tampered with, can not pass parameters

6. parasitic combined inheritance #

Core: combination of borrowing constructor passing parameters and parasitic mode of inheritance

  1. Parent class to inherit this declaration by borrowing constructor (call) Attribute / Method
  2. Inherit methods through the prototype chain           

 

function Father (name, Age) {
     the this .name = name;
     the this .age = Age; 
} 
Father.prototype.getFatherName = function () { 
    the console.log ( 'parent class' ) 
} 

function Son (name, Age, Job) { 
    Father.call ( this , name, Age); // borrow configured inheritance: the properties inherited from the parent class to sub-class instance attributes declared by this method and 
    this .job = Job; 
} 

// parasitic succession: a package the son.prototype object prototype style process father.prototype inheritance, and enhances the incoming object. 
function inheritPrototype (Son, Father) {
     var clone = the Object.create (father.prototype);// prototypal inheritance: a shallow copy father.prototype objects 
    clone.constructor = Son;   // enhanced object compensate for the loss of the prototype rewrite the default constructor property 
    son.prototype = clone; // specified object, the newly created prototype object is assigned to the subclass 
} 
inheritPrototype (son, father); // to point to the parent class prototype subclass 

// new subclass prototype properties 
Son.prototype.getSonName = function () { 
    the console.log ( 'subclass method ' ) 
} 

var Son = new new Son (' Jacky ', 22 is,' front-end development ' ); 
the console.log (Son);
  • Inheritance parasitic modular succession with respect to composition has the following advantages:
  1. Father called only once parent constructor. You do not have to specify the prototype subclass and call the constructor, but let Son.prototype indirect access to Father.prototype.
  2. Avoid creating unnecessary excess property on the child class prototype. Formula inherited prototype prototype parent class, the prototype chain context maintained unchanged, and the instanceof isPrototypeOf () can be used normally. 3. Combined parasitic inheritance is the most mature inherited methods, it is now the most common inherited methods, many JS library uses inheritance scheme is it.

Disadvantages:

After insist, then, it is to subclass prototype to add properties and methods, be sure to put inheritPrototype () method

 

7.ES6 extends inheritance (the best way) #

Core: implementation inheritance by keyword extends between classes, clear and easy. class is just a syntactic sugar, its core idea is still parasitic combined inheritance.

Father {class 
  constructor (name, Age) { 
    the this .name = name;
     the this .age = Age; 
  } 
  skill () { 
    the console.log ( 'parent class skills' ); 
  } 
} 

class the extends Father Son { 
  constructor (name, Age, Job) { 
    Super (name, Age); // call the constructor of the superclass, only after calling super, this keyword can use 
    this .job = Job; 
  } 

  getInfo () { 
    the console.log ( this .name, the this .age, the this .job); 
  } 
} 


the let Son = new newSon ( 'jacky', 22, ' front-end development' ); 
son.skill (); // skill parent class 
son.getInfo (); // Jacky 22 is front-end development
  • If the child class does not define constructor method, which will be included by default, as follows. In other words, whether or not explicitly defined, any sub-class has a constructor method.

The subclass must call the super method in the constructor method, otherwise it will error when creating a new instance. This is because their own subclass this object must be finished by shaping the parent class constructor, to give examples of the same properties and methods of the parent class, then its processing, plus their own subclass instance attributes and methods. If you do not call the super method, the subclass will not get this object.

ES5 and ES6 inherited inherited differences #

  1. ES5 inheritance is essentially to create an instance of a subclass, then the parent class method is added to this (Father.call (this)).
  2. Inheritance ES6 is to first create an instance of this object is the parent class, then subclass constructor changes this.
  3. Because the subclass does not own this object, you must first call the super () method of the parent class.

 

Transfer the contents of the Nuggets community JackySummer , the original link    https://juejin.im/post/5dd55918e51d4536db238a19

 

Guess you like

Origin www.cnblogs.com/yetiezhu/p/12093055.html
Recommended