1. Prototype inheritance

Archetypal inheritance is a common way of inheritance

function Parent() {
  this.name = 'parent'
  this.action = function () {
    console.log(this.name)
    return this.name
  },
  this.arr = [1.2]
}

Parent.prototype.getName = function () {
  console.log(this.name)
  return this.name
}

function Child() {
  this.name = 'child'
}
// Instantiate the parent function and link it to its own prototype chain
Child.prototype = new Parent
const child1 = new Child
console.log(child1)
Copy the code

Prototype inheritance: inherit the public (prototype) and private (private) attributes of the parent class to the prototype of the subclass.

Note: The downside of stereotype inheritance

  const child2 = new Child
  console.log(child1)
  child2.arr.push(3)
Copy the code

If I have a subclass child2 that calls the parent class’s arr property and adds something then I’m going to look at child1 and child2As you can see from the above results, child2 modifies the parent class attributes, and child1 modifies the parent class attributes. This makes sense because they both inherit from the same parent. Their memory space is shared. So:Disadvantages of stereotypes: Subclasses share the memory space of their parent class

Constructor inheritance (borrowing call or apply)

function Parent() { this.name = 'parent' this.action = function () { console.log(this.name) return this.name }, GetName = function () {console.log(this.name) return this.name}Copy the code

This solves the problem of data sharingBut:Only instance properties and methods of the parent class can be inherited, not stereotype properties or methods.

Composite Inheritance (Call + Prototype)

function Parent() {
  this.name = 'parent'
  this.action = function () {
    console.log(this.name)
    return this.name
  },
  this.arr = [1.2]
}
Parent.prototype.getName = function () {
  console.log(this.name)
  return this.name
}

function Child() {
  this.name = 'child'
  Parent.call(this)
}
Child.prototype = new Parent
Child.prototype.constructor = Child
const child1 = new Child
console.log(child1)
Copy the code

Advantages: Solves the disadvantages of stereotype inheritance and constructor inheritance. However, there are drawbacks to this approach: as you can see from the figure above, the subclass stereotype has an extra copy of the parent class instance attributes. Because the constructor of the parent class is called twice, generating two copies, the one on the subclass instance masks the one on the prototype, resulting in a memory waste

Parasitic inheritance (Object.create)

Is to use prototype inheritance to get a shallow copy of an object. Then use this shallow copy object to enhance. The disadvantages are the same as stereotype inheritance, but for ordinary object inheritance, you can add more methods to the parent class

let Parent1 = {
  arr: ['a'.'b'].name: 'Parent1'.getName: function() {
    return this.name
  }
}
function Child(parent) {
  let copy = Object.create(parent)
  console.log(copy)
  copy.getArray = function () {
    return this.arr
  }
  return copy
}

let Child1 = Child(Parent1)
console.log(Child(Parent1))
console.log('child1 -->', Child1.getArray()) // ['a', 'b']
console.log('child1 -->', Child1.getName()) // Parent1
Copy the code
  • Defects cannot be instantiated and stereotypes are not used.

Parasitic combinatorial inheritance

function Parent() { this.name = 'parent' this.action = function () { return this.name }, Prototype = function () {return this.name} function Child() {parent.call (this)} Child.prototype = Object.create(Parent.prototype) Child.prototype.constructor = Child const child1 = new Child const child2 = new Child console.log(child1)Copy the code
  • To solve the above several kinds of defects, but also better to achieve the result of inheritanceIn subclass private, attributes and methods on the stereotype are placed on the subclass stereotype

Note: the above written inheritance, why want to manually modify the constructor to because: in the regulation of JS, XXX. Prototype. Pointing to the constructor is the current function (class). Parent (); Parent (); Parent (); Parent (); Parent (); Parent (); Parent ()

// Child.prototype.constructor = Child
 console.log('constructor -->', Child.prototype.constructor === Parent) // true 
Copy the code

Without manual referencing, Child’s constructor points to Parent, thus violating the standard JS specification.

ES6 extends keyword

In ES6, JavaScript inheritance is easy to implement using the extends keyword directly, and Babel, after editing it, takes the form of parasitic composite inheritance, which is a better way to handle inheritance.

class Parent2 {
  constructor(name) {
    this.name = name
  }
  getName = function (){
    return this.name
  }
}
class Child2 extends Parent2 {
  constructor(name, age) {
    super(name)
    this.age = age
  }
}
const child3 = new Child2('parent'.22)
const child4 = new Child2('parent1'.25)
console.log(child3.getName())
console.log(child3)
console.log(child4)
Copy the code