Inheritance of class!

Implement an inheritance;

Let’s start with a simple example


class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return this.x + The '-' + this.y
  }
}

class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // Call parent constructor(x, y)
    this.color = color;
  }

  toString() {
    return this.color + ' ' + super.toString(); // Call the parent toString()}}let p = new ColorPoint(10.20.'red')

// ColorPoint {x: 10, y: 20, color: 'red'}
// color: "red"
// x: 10
// y: 20
Copy the code

The above example is a relatively simple inheritance; ES6 class inheritance; In a subclass, you need to call super, which points to the constructor of the parent class; Passing the argument to the parent class and referring this in the parent constructor to an instance of the subclass constructor is why we call super;

Second, extension,

If the subclass does not define a constructor method, this method is added by default, as shown below. That is, any subclass has a constructor method regardless of whether it is explicitly defined;

class ColorPoint extends Point {}/ / is equivalent to
class ColorPoint extends Point {
  constructor(. args) {
    super(...args);
  }
}
Copy the code

Another thing to note is that in the constructor of a subclass, the this keyword can only be used after super is called, otherwise an error will be reported. This is because subclass instances are built on superclass instances, and only super methods can call superclass instances;

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y; }}class ColorPoint extends Point {
  constructor(x, y, color) {
    this.color = color; // ReferenceError
    super(x, y);
    this.color = color; / / right}}Copy the code

3. Analyze the principle of super;

There are two cases, first when super is executed as a function and second when super is used as an object;


class A {}

class B extends A {
  constructor() {
    super();
  }
}

Copy the code

Super first calls the constructor of the superclass, and then refers the “this” in the superclass constructor to the subclass.


super == A.constructor.apply(this,args)  // This is an instance of class B

// super --> Parent.constructor.apply(this,args)
// Super cannot be executed as a function in a method or an error will be reported;

Copy the code

In the above case, super is executed as a function; When super is executed as an object, it can be called in a method;


class A {
  p() {
    return 2; }}class B extends A {
  constructor() {
    super(a);console.log(super.p()); / / 2}}let b = new B();
// It is important to note that since super refers to the parent's prototype object, methods or properties defined on the parent instance cannot be called by super.
Copy the code

When super is an object, in a normal method or constructor, it points to the prototype object of the parent class; In static methods, point to the parent class.

Summary: where and how to call super

1. as a function

  • Can only be called in the constructor; Constructor that points to the parent class

1. As an object

  • Call the prototype object pointing to the parent class in the constructor and function
  • Calls to the parent class in static methods

Fourth, inheritance related

class A {}class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype 
Copy the code

The __proto__ attribute of a subclass always points to its parent class; The __proto__ attribute of the prototype attribute, which indicates method inheritance, always points to the Prototype attribute of the parent class.

Principle of inheritance

Class inheritance can be implemented through Object.setPrototypeof ();

/ / such as
class A {}
class B extends A {}

// To implement the above inheritance relationship, you can do;

Object.setPrototypeOf(B.prototype , A.prototype)
Object.setPrototypeOf(B , A)

// Here setPrototypeOf implementations can look like this;

Object.setPrototypeOf = function (obj, proto){
  obj.__proto__ = proto;
  return obj;
}


/ / so

B.prototype.__proto__ = A.prototype;   // true
B.__proto__ = A  // true

Copy the code

Instance inheritance

/ / such as
class A {}
class B extends A {}

const a = new A()
const b = new B()
a.__proto__ === b.__proto__ // false
a.__proto__.__proto__ === b.__proto__ // true
Copy the code