1. Class inheritance

Let’s start with the prototype

function Animal(){}let a1 = new Animal()

// The implicit prototype of each object attribute refers to its parent's prototype
// Because Animal is constructed from function, its implicit prototype refers to the prototype of function
console.log(Animal.__proto__ === Function.prototype);    //true
// According to the prototype relationship between Function and Object, we can get such a relationship
console.log(Animal.prototype.__proto__ === Object.prototype);   // true
// The implicit prototype of any instantiated object (__proto__) refers to its parent prototype
console.log(a1.__proto__ === Animal.prototype);   //true
console.log(a1 instanceof Object);   //true
console.log(a1.__proto__ === Object.protortpe)   // false

// Basic conclusion: The implicit prototype of any instantiated object (__proto__) refers to its parent (protorypr).
// Just to be sure
let temp = {}
console.lot(temp.__proto__ === Object.prototype)  //true

// The creation of the prototype chain, and the emergence of the first type of inheritance
console.log(a1.__proto__.__proto__ === Object.prototype);   // true
Copy the code

The first method of inheritance is to direct the prototype of the child object to an instance of the parent, so that the __proto__ of the child object points to the parent class

function Animal (name){
    this.name = 'animal' 
    this.say = function(){
      console.log(this.name);
    }
    this.setName = function(name){
      this.name = name
    }
}

function Cat(name){      }

Cat.prototype = new Animal()

const RagaMuffin = new Cat()
RagaMuffin.say()      // animal
RagaMuffin.setName('Ragged Cat')
RagaMuffin.say()      / / rags cat
console.log(RagaMuffin);
// Disadvantages: parent attributes are shared. Modifying parent attributes affects other instances
RagaMuffin.__proto__.name = 'Ragged Cat'

const Tabby = new Cat()
Tabby.say()           / / rags cat
Tabby.setName("Tabby")
Tabby.say()           / / tabby cat
console.log(Tabby);
Copy the code

Advantages:

  1. Intuitive and simple inheritance of the parent method

Disadvantages:

  1. Unable to receive dynamic parameters for subclasses
  2. Parent attribute sharing

Constructor inheritance

function Animal (name){
    this.name = name 
    this.say = function(){
      console.log(this.name); }}// Add methods to the prototype
Animal.prototype.eat = function(){
    console.log(this.name , 'fish');
}
// Create a subclass
function Cat(name){    
    Animal.call(this, name)
}

const RagaMuffin = new Cat('Ragged Cat')
RagaMuffin.say()      / / rags cat
RagaMuffin.eat()      // RagaMuffin.eat is not a function
Copy the code

Disadvantages:

  1. Constructor inheritance fails to inherit methods from the parent stereotype

3. Combinatorial inheritance

A method that combines the two types of inheritance is called combinatorial inheritance

  function Animal (name){
    this.name = name 
    this.say = function(){
      console.log(this.name);
    }
    Animal.prototype.eat = function(){
      console.log(this.name , 'fish'); }}function Cat(name){    
    Animal.call(this, name)
  }

  Cat.prototype = new Animal()
  const RagaMuffin = new Cat('Ragged Cat')
  console.loe(RageMyffin)   
  RagaMuffin.say()      / / rags cat
  RagaMuffin.eat()      // The ragged cat eats fish
Copy the code

Disadvantages:

  1. A subclass cannot pass dynamic parameters to its parent class
  2. The constructor of the parent class is called twice

4. Original type inheritance

function createObject(o) {
    // Create temporary classes
    function f() {}// Change the prototype of the class to O, so that instances of F will inherit methods on O
    f.prototype = o
    return new f()
}

const obj = {
name: 'chang'
}
const chang = createObject(obj)
console.log(chang.name);        // chang
Copy the code

Disadvantages: Shared properties and methods do not address the disadvantages of class inheritance

5. Parasitic inheritance

Create a function that encapsulates only the inheritance process, internally does the enhancement object in some form, and finally returns the object

function createAnother(original) {
  var clone = Object.create(original);    Create a new object by calling the function
  clone.say = function () {               // Enhance the object in some way
    console.log('Hello');
  };
  return clone;                        // Return this object
}

const obj = {
  name: 'chang'.testArr: [1.2.3]}const newObj = createAnother(obj)
console.log(newObj.name);     // chang
newObj.say()                  // Hello
newObj.testArr.push(4)
console.log(newObj.testArr);  //(4) [1, 2, 3, 4]
Copy the code

6. Parasitic combination inheritance

function inherit(child, parent) {
      // Get the parent's prototype
      const parent_proto = Object.create(parent.prototype)
      // Subclasses inherit from their parent class
      child.prototype = parent_proto
      // The parent class constructor points to child to prevent contamination
      parent_proto.constructor = child
    }

    / / parent class
    function Animal(name) {
      this.name = name
      this.say = function () {
        console.log(this.name);
      }
      Animal.prototype.eat = function () {
        console.log(this.name, 'fish'); }}/ / subclass
    function Cat(name) {
      Animal.call(this, name)
    }

    inherit(Cat, Animal)


    const RagaMuffin = new Cat('Ragged Cat')
    console.log(RagaMuffin);
    RagaMuffin.say()      / / rags cat
    RagaMuffin.eat()
Copy the code