The implementation of JS inheritance

To implement inheritance, we need to have a parent class that looks like this:

/ / define a Animal function Animal (name) {/ / attribute this. Name = name | | 'Animal' / / instance methods this. Sleep = function () { Console. log(this.name + 'Sleeping! ')} // Animal.prototype.eat = function(food) {console.log(this.name + 'eating:' + food); };Copy the code

1. Prototype chain inheritance

Core: Use an instance of a parent class as a prototype for a subclass

function Cat(){}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';

var cat = new Cat();
console.log(cat.name); 
console.log(cat.eat('fish'));
console.log(cat.sleep()); 
console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true
Copy the code

Features:

  1. Very pure inheritance, an instance is an instance of a subclass and an instance of a parent class
  2. New stereotype methods/attributes in the parent class that are accessible to all subclasses
  3. Simple and easy to implement

Disadvantages:

  1. To add attributes and methods to a subclass, you must specify thenew Animal()Such statements are executed later and cannot be placed in the constructor
  2. Multiple inheritance cannot be implemented
  3. All properties from the stereotype object are shared by all instances
  4. Cannot pass arguments to the parent constructor when creating a subclass instance

2. Structural inheritance

Core: Using the constructor of the parent class to enhance the instance of the child class is equivalent to copying the instance properties of the parent class to the child class (without using the stereotype).

function Cat(name){ 
    Animal.call(this); 
    this.name = name || 'Tom'; 
}

var cat = new Cat(); 
console.log(cat.name);
console.log(cat.sleep()); 
console.log(cat instanceof Animal); // false 
console.log(cat instanceof Cat); // true
Copy the code

Features:

  1. Fixed the problem of subclass instances sharing parent class reference attributes in 1
  2. When you create a subclass instance, you can pass parameters to the parent class
  3. Multiple inheritance can be implemented (call multiple parent objects)

Disadvantages:

  1. An instance is not an instance of a parent class, only an instance of a subclass
  2. Only instance properties and methods of the parent class can be inherited, not stereotype properties/methods
  3. Function reuse is not possible, each subclass has a copy of the parent class instance function, affecting performance

3. Instance inheritance

Core: Adds new features to the parent class instance and returns it as a subclass instance

function Cat(name){ 
    var instance = new Animal(); 
    instance.name = name || 'Tom'; 
    return instance; 
}

var cat = new Cat(); 
console.log(cat.name); 
console.log(cat.sleep()); 
console.log(cat instanceof Animal); // true 
console.log(cat instanceof Cat); // false
Copy the code

Features:

  1. There are no restrictions on how to call, eitherNew subclasses ()orSubclasses (), the returned object has the same effect

Disadvantages:

  1. An instance is an instance of a parent class, not a subclass
  2. Multiple inheritance is not supported

Copy inheritance

function Cat(name){ 
    var animal = new Animal(); 
    for(var p in animal){ 
        Cat.prototype[p] = animal[p]; 
    }  
    this.name = name || 'Tom'; 
}

var cat = new Cat(); 
console.log(cat.name); 
console.log(cat.sleep()); 
console.log(cat instanceof Animal); // false 
console.log(cat instanceof Cat); // true
Copy the code

Features:

  1. Support for multiple inheritance

Disadvantages:

  1. Low efficiency and high memory footprint (due to copying parent class attributes)
  2. Unable to get non-enumerable methods of the parent class (non-enumerable methods, not accessible using for in)

5. Combinatorial inheritance

Core: Inherits the attributes of the parent class and retains the advantages of passing arguments by calling the parent class constructor, and then implements function reuse by using the parent class instance as a subclass prototype

function Cat(name){ 
    Animal.call(this); 
    this.name = name || 'Tom'; 
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;

var cat = new Cat(); 
console.log(cat.name); 
console.log(cat.sleep()); 
console.log(cat instanceof Animal); // true 
console.log(cat instanceof Cat); // true
Copy the code

Features:

  1. To remedy the weakness of approach 2, you can inherit instance properties/methods as well as stereotype properties/methods
  2. Both an instance of a subclass and an instance of a superclass
  3. There is no reference property sharing problem
  4. Can pass the cords
  5. Function reuse

Disadvantages:

  1. The parent constructor is called twice, generating two instances (the subclass instance hides the subclass prototype)

6. Parasitic combination inheritance

Core: By parasitic way, the instance attributes of the parent class are cut off, so that when the constructor of the parent class is called twice, the two instance methods/attributes are not initialized, avoiding the disadvantages of combinative inheritance

function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } (function(){var Super = function(){}; Super.prototype = Animal.prototype; Cat.prototype = new Super(); }) (); var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true Cat.prototype.constructor = Cat;Copy the code

Features:

  1. perfect

Disadvantages:

  1. Implementation is complicated