1. Prototype chain inheritance

Core:

Use an instance of a parent class as a prototype for a subclass.

Advantages:

  • Simple implementation.

Disadvantages:

  • Stereotype attributes that contain reference type values are shared by all instances, causing changes to one instance to affect the other.
  • To add attributes and methods to a subclass, it must be executed after a statement such as new Cat(), not in a constructor. For example, when creating an instance of Child, no arguments are passed to Cat. Because of these two problems, prototype chains alone are rarely used in practice.
// Prototype chain inheritance
function SuperType() {
  this.name = 'zhangsan';
}
SuperType.prototype.sayName = function() {
  console.log(this.name);
}
function SubType() {}
// An instance of the parent class is the prototype of the subclass
SubType.prototype = new SuperType();

/ / test
let instance1 = new SubType();
instance1.sayName();
Copy the code

2. Borrow constructor inheritance

Core:

Importing a superclass constructor into a subclass function with.call() or.apply() copies the instance attributes of the superclass to the subclass.

Advantages:

  • 1. Only the attributes of the parent constructor are inherited, and no attributes of the parent prototype are inherited.
  • 2. Two shortcomings of prototype chain inheritance are solved.
  • 3. Can inherit multiple constructor properties (call multiple)
  • 4. In a child instance, you can pass parameters to the parent instance.

Disadvantages:

  • 1. Only attributes of the parent constructor can be inherited.
  • 2. Constructor reuse cannot be realized. (It needs to be called again each time it is used)
  • 3. Each new instance has a bloated copy of the superclass constructor. So borrowed constructor inheritance is rarely used in isolation.
// borrow constructor inheritance
function SuperType(name) {
  this.name = name;
}
function SubType(name,age) {
  SuperType.call(this,name);
  this.age = age;
}

/ / test
let person1 = new SubType('zhangsan'.22);
console.log(person1.name);
console.log(person1.age);
Copy the code

3. Combinatorial inheritance

Core:

Inheritance of instance attributes is achieved through constructors, and inheritance of methods is achieved through stereotype chains.

Advantages:

  • 1. Can inherit the attributes of the parent class prototype, can pass parameters, can reuse.
  • 2. Constructor properties introduced by each new instance are private.

Disadvantages:

  • The parent constructor is called twice (call once, new once), and the subclass’s constructor replaces the prototype’s parent constructor.
// Combinatorial inheritance
/ / parent class
function SuperType(name) {
  this.name = name;
  this.colors = ['blue'.'red'];
}
// Parent method
SuperType.prototype.sayName = function() {
  console.log(this.name);
}
/ / subclass
function SubType(name,age) {
  // Inheritance attributes construct inheritance
  SuperType.call(this,name);
  this.age = age;
}
// Inheritance method prototype inheritance
SubType.prototype = new SuperType()
// Subclass methods
SubType.prototype.sayAge = function() {
  console.log(this.age);
}

/ / test
let person1 = new SubType('zhangsan'.22);
person1.sayName();
person1.sayAge();
person1.colors.push('black');
console.log(person1.colors);
Copy the code

4. Original type inheritance

Core:

A mock implementation of ES5 Object.create that uses the passed Object as a prototype for the created Object.

Advantages:

  • Refer to prototype chain inheritance

Disadvantages:

  • Refer to prototype chain inheritance
// Original type inheritance
// Encapsulate a function container that outputs objects and holds inherited stereotypes
function createObj(o) {
  function F() {}
  F.prototype = o; // Inherits the parameters passed in
  return new F(); // Return the function object
}

/ / test
letPerson = {name:'zhangsan'.friends: ['lisi'.'wangwu']}let person1 = createObj(person);
let person2 = createObj(person);
person1.name = 'person1';
console.log(person2.name);
person1.friends.push('zhou');
console.log(person2.friends);
Copy the code

Parasitic inheritance

Core:

It’s just a case of the original inheritance.

Advantages:

  • Instead of creating a custom type, the function returns the object in a shell, and becomes the new object to be created.

Disadvantages:

  • As with the borrowed constructor model, methods are created each time an object is created.
  • No prototype, no reuse.
// Parasitic inheritance
// There is a function outside the original form
function createObj(o) {
  // This step is shorthand for primitive inheritance
  let clone = Object.create(o);
  // Add attributes
  clone.sayName = function() {
    console.log('hi');
  }
  return clone; // Return this object
}

/ / test
function child() {}
let child1 = createObj(child)
child1.sayName()
Copy the code

Parasitic combinatorial inheritance

Core:

Using parasitic inheritance to inherit the parent archetype and then assign the new object returned to the child archetype, parasitic composite inheritance is probably the best model for reference type inheritance.

// Parasitic combinatorial inheritance
/ / parent class
function SuperType(name) {
  this.name = name;
  this.colors = ['blue'.'red'];
}
SuperType.prototype.sayName = function() {
  console.log(this.name);
}
/ / subclass
function.SubType(name,age) {
  SuperType.call(this,name);
  this.age = age;
}
// Encapsulate an inheritance function
function extend(subtype,supertype) {
  let prototype = Object(supertype.prototype);
  prototype.constructor = subtype;
  subtype.prototype = prototype;
}
/ / call
extend(SubType,SuperType)

/ / test
SubType.prototype.sayAge = function() {
  console.log(this.age);
}
let person1 = new SubType('zhangsan'.22);
person1.sayName();
person1.sayAge();
person1.colors.push('black');
console.log(person1.colors);
Copy the code