This is the third day of my participation in Gwen Challenge

The title

Implement the following ES6 inheritance in ES5 code

class Parent {
    static author = 'LvLin';
    constructor(name) {
        this.name = name;
    }
    getName() {
        return this.name;
    }
    static getAuthor() {
        returnParent.author; }}class Child extends Parent {
    constructor(name, age) {
        super(name);
        this.age = age;
    }
    sayHello() {
        console.log('Hello, I am ' + super.getName());
    }
    static printAuthor() {
        console.log(super.getAuthor()); }}Copy the code

implementation

Prototype Chain Implementation Inheritance (extends)

Inheritance is a concept in object-oriented software technology. If A class B inherits from A class A, B is called A subclass of A and A is called the parent of B. Inheritance gives a subclass the properties and methods of its parent class and eliminates the need to write the same code, but a subclass can append new properties and methods or override the properties and methods of its parent class.

Each language has its own inheritance mechanism, and JavaScript inheritance is implemented through the prototype chain. Attributes and methods that need to be inherited are defined in the constructor’s prototype. When the instance object cannot find an associated property or method on itself, it looks for the parent’s property or method on the prototype chain. See this article for more information.

let child = new Child()
child.__proto__ === Child.prototype     // true
child.__proto__.__proto__ === Parent.prototype     // true
child.getName === Parent.prototype.getName     // true
Copy the code

ES5: static, super, ES6: static, super

function Parent (name) {
    this.name = name;
}

Parent.prototype.getName = function() {
    return this.name;
}
Parent.prototype.constructor = Parent;

function Child (name, age) {
    / /... The super keyword exists, later implemented
}

Child.prototype = new Parent();  // This step can be optimized
Child.prototype.constructor = Child;
Copy the code

Prototype = new Parent(); parent.prototype = new Parent();

var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Copy the code

The static implementation

Static properties, static methods (static), are defined in the properties of the Class itself, only through a kind of call, for all instances to share, not be inherited, so cannot be defined in the prototype, defined in the constructor itself, as follows:

Parent.getAuthor = 'LvLin';
Parent.getAuthor = function() {
    return Parent.author;
}
Copy the code

Super implementation

In ES6, super can be either a function or an object, in two cases:

  1. When called as a function, represents the constructor of the parent class.
  2. As an object, in a normal method, a prototype object that points to the parent (note the reference to this in this case); In static methods, point to the parent class.

So super in ES6 class inheritance can be rewritten as the following ES5 code:

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}

Child.prototype.sayHello = function() {
    console.log('Hello, I am ' + Parent.prototype.getName().call(this));
}

Child.printAuthor = function() {
    console.log(Parent.getAuthor());
}

Copy the code

The final result

Combined with the above analysis, the final rewrite of ES5 code is as follows:

function Parent (name) {
    this.name = name;
}

Parent.prototype.getName = function() {
    return this.name;
}
Parent.prototype.constructor = Parent;
Parent.author = 'LvLin';
Parent.getAuthor = function() {
    return Parent.author;
}

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}

var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;

Child.prototype.sayHello = function() {
    console.log('Hello, I am ' + Parent.prototype.getName().call(this));
}
Child.printAuthor = function() {
    console.log(Parent.getAuthor());
}
Copy the code

Test it out:

let child = new Child('LvLin'.18)
child.sayHello()   // Hello, I am LvLin
child.getName()    // "LvLin"
Child.printAuthor()    // LvLin
Copy the code

Finally, there are two prototype chains in ES6 class inheritance. There are also inheritance relationships between classes. Try:

Child.__proto__ === Parent  // true
Copy the code

reference

Basic syntax of Class, inheritance of Class, by Ruan Yifeng

JavaScript dive from prototype to prototype chain, multiple ways of JavaScript dive inheritance and pros and cons, by Yuba Hu