As we all know, before ES6, there was no syntactic sugar for classes in the front end, so you couldn’t use the extends keyword to fix inheritance as in other languages, and you needed some extra methods to implement inheritance. The following is to introduce some commonly used methods, the Little Red Book has been summarized very comprehensive, so this article is basically the little Red Book to inherit the chapter notes and combing.

Prototype chain inheritance

function Parent() {
    this.name = 'arzh'
}

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

function ChildMain essence () {} / / Child. The prototype = new Parent () the Child. Child var arzhChild prototype. The constructor = = new Child () arzhChild.getName() //'arzh'
Copy the code

Disadvantages of prototype chain inheritance:

  1. Changes made by each instance to a reference type attribute are shared by other instances
function Parent() {
    this.names = ['arzh'.'arzh1'];
}

function ChildMain essence () {} / / Child. The prototype = new Parent () the Child. Child var arzhChild2 prototype. The constructor = = new Child () arzhChild2.names.push('arzh2')
console.log(arzhChild2.names) //[ 'arzh'.'arzh1'.'arzh2' ]

var arzhChild3 = new Child()
arzhChild3.names.push('arzh3')
console.log(arzhChild3.names) //[ 'arzh'.'arzh1'.'arzh2'.'arzh3' ]
Copy the code
  1. When creating aChildThe instance cannot be queriedParentThe refs. This will make itChildInstance cannot customize its own property (name)

Borrowing constructors (classical inheritance)

function Parent() {
    this.names = ['arzh'.'arzh1']}function Child() {
    Parent.call(this)
}

var arzhChild2 = new Child()
arzhChild2.names.push('arzh2')
console.log(arzhChild2.names) //[ 'arzh'.'arzh1'.'arzh2' ]

var arzhChild3 = new Child()
arzhChild3.names.push('arzh3')
console.log(arzhChild3.names) //[ 'arzh'.'arzh1'.'arzh3' ]
Copy the code

Advantages:

  1. Fixed the problem of each instance making changes to a reference type attribute being shared by other instances
  2. A subclass can pass arguments to its parent class
function Parent(name) {
    this.name = name
}

function Child(name) {
    Parent.call(this, name)
}
    
var arzhChild = new Child('arzh');

console.log(arzhChild.name); // arzh

var arzhChild1 = new Child('arzh1');

console.log(arzhChild1.name); // arzh1

Copy the code

Disadvantages:

  1. Cannot reuse a public function of a parent class
  2. The superclass function must be executed every time a subclass constructs an instance

Combinatorial inheritance (stereotype chain inheritance and borrowing constructor merge)

function Parent(name) {
    this.name = name
    this.body = ['foot'.'hand']}function Child(name, age) {
    Parent.call(this, name)
    this.age = age
}

Child.prototype = new Parent()
Child.prototype.constructor = Child

var arzhChild1 = new Child('arzh1'.'18')
arzhChild1.body.push('head1')
console.log(arzhChild1.name,arzhChild1.age) //arzh1 18
console.log(arzhChild1.body) //[ 'foot'.'hand'.'head1' ]

var arzhChild2 = new Child('arzh2'.'20')
arzhChild2.body.push('head2')
console.log(arzhChild2.name,arzhChild2.age) //arzh2 20
console.log(arzhChild2.body) //[ 'foot'.'hand'.'head2' ]
Copy the code

Advantages:

  1. Fixed the problem of each instance making changes to a reference type attribute being shared by other instances
  2. A subclass can pass arguments to its parent class
  3. Can realize the parent class method reuse

Disadvantages:

  1. The parent constructor needs to be executed twice, the first timeChild.prototype = new Parent()The second time isParent.call(this, name)Cause unnecessary waste

Primary inheritance

Inheritance is achieved by copying the passed object to the prototype that created the object

function createObj(o) {
    function F(){}
    F.prototype = o;
    return new F();
}
var person = {
    name : 'arzh',
    body : ['foot'.'hand']
}
var person1 = createObj(person)
var person2 = createObj(person)

console.log(person1) //arzh
person1.body.push('head') 
console.log(person2) //[ 'foot'.'hand'.'head' ]
Copy the code

Disadvantages: As with stereotype chain inheritance, each instance’s modification of a reference type attribute is shared by the other instances

Parasitic inheritance

We can use Object.create instead of the createObj implementation above, and the principle is basically the same. Parasitic inheritance is simply a way to enhance an object inside createObj in some form, and then return the enhanced object.

functionCreateEnhanceObj (o) {// Replace the createObj var inherited from the original formclone = Object.create(o)
    clone.getName = function () {
        console.log('arzh')}return clone;
}
Copy the code

CreateEnhanceObj allows object methods to be inherited in this way when an object is created. Disadvantages: Like borrowing constructors, you can’t reuse a parent function, creating a method every time you create an object

Parasitic combinatorial inheritance

There is no need to new the Parent constructor for the Child’s prototype, such as child.prototype = new Parent(). Just copy a copy of the Parent to the Child’s prototype

functioninheritPrototype(Parent, Child) {Child. Prototype = Object. The create (Parent. The prototype) / / create a copy of the Parent class archetype, the copy of the assignment to subclass prototype Child. The prototype. The constructor = Child; }function Parent(name) {
    this.name = name
}

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

function Child(color) {
    Parent.call(this, 'arzh')
    this.color = color
}

inheritPrototype(Parent, Child)

var arzhChild = new Child('red')
console.log(arzhChild.name) // 'arzh'

Copy the code

Advantages: You do not need to call the parent type’s constructor to specify the stereotype of the child type

ES6 inheritance

ES6 supports inheritance through classes, the method is relatively simple, the code is as follows

class Point {
    constructor(x, y) {
        this.x = x
        this.y = y
    }
    
    toString() {
        return this.x + ' '+ this. Y}} class ColorPoint extends Point {constructor(x, y, color) {super(x, y)} y) this.color = color }toString() {
        return this.color + ' '+ super.toString()}} var colorPoint = new colorPoint ()'1'.'2'.'red')

console.log(colorPoint.toString())  // red 12
Copy the code

For any optimization suggestions in this paper, you can scan the following TWO-DIMENSIONAL code to discuss, but also hope that you pay more attention to, will send some original articles from time to time