preface

This article is based on teacher Ruan’s ES6 tutorial. When I saw the super keyword, I felt it was necessary to summarize and comb through it. The original text is still referred to ECMAScript 6 for introduction.

The body of the

The super keyword can be used as either a function or an object.

1. Use as a function

When called as a function, super represents the constructor of the parent class. ES6 requires that the constructor of a subclass must execute the super function once.

That is, when using the following code as a function:

class A {
   constrctor(){
   }
}

class B extends A {
   constructor() { super(); }}Copy the code

Who does super() stand for in the code above?

Super () in the constructor of subclass B is executed on behalf of B by calling the constructor of its parent class A.

Note ⚠ ️ : Although super() represents the constructor of superclass A, it returns an instance of subclass B, i.e. this inside super() refers to B, So super () is equivalent to Amy polumbo rototype here. The constructor. Call (this).

To prove my point with a big chestnut:

class A {
    constrctor(){
        console.log(new.target.name)
    }
}

class B extends A{
    constructor(){
        super()
    }
}
new A() // A
new B() // B
Copy the code

In this steamy piece of code, new.target points to the function currently executing.

To recap:

New is the command to generate the instance object from the constructor. ES6 introduces a new.target attribute for the new command, which is typically used in constructors to return the constructor on which the new command is applied.

As you can see, when super() executes, it points to the constructor of subclass B, not the constructor of superclass A. This inside super() refers to B.

Another point to note ⚠️ :

When used as a function, super() can only be used in the constructor of a subclass and is used elsewhere to report an error.

Class A {} class B extends A {m() { super(); // Error}}Copy the code

To sum up:

Note the following three points when super is used as a function:

  1. The constructor of a subclass must be executed oncesuperFunction.
// Class A {class A {constructor() {}
}

class B extends A {
  constructor() { super(); // this is a.constructor ()}}Copy the code
  1. In the constructor of a subclassSuper ()When a subclass calls the parent class’s constructorsuper()In this, namelyThe parent class constructorIn thethis, pointing to a subclass.

3. Super () can only be used in the constructor of a subclass; using it elsewhere will cause an error.

2. When super is an object

When super is an object, it points to the parent class in a normal method and to the parent class in a static method.

2.1 Super is applied as an object in ordinary methods

The code:

class A {
    p() {return 2
    }
}

class B extends A {
    constrctor(){ super(); console.log(super.p()); / / 2}}let b = new B();

Copy the code

We find that super.p() executes 2 in subclass B. Supsuper. p === a.prototype. p;

class A {
  p() {
    return 2;
  }
}

class B extends A {
  constructor() {
    super();
    console.log(super.p===A.prototype.p); // true}}let b = new B();
Copy the code

That is, at this point in the normal method, super refers to a.protoType that is, super in the subclass refers to the prototype object of the parent class.

⚠️ Note 1. Since super in a subclass refers to the prototype object of the parent class, methods or properties defined on instances of the parent class cannot be called by super.

class A {
   constructor() {
    this.s = 3;
   }
}

A.prototype.x = 2;

class B extends A {
  constructor() { super(); Console. log(super.x) // 2 Here you can get the x property on the superclass prototype} getm() {return super.s
  }
}

letb = new B(); Console. log(b.m)// undefined cannot get the S attribute defined on the parent instanceCopy the code

Through the above code we found:

Subclass B can use super to get the attributes defined by the parent class on the stereotype, but the attributes defined by the parent class on the instance of the parent class A cannot be obtained.

Note 2⚠️ : this points to

ES6 states that when a method of a parent class is called through super in a subclass normal method, this inside the method refers to the current subclass instance.

class A {
  constructor() {
    this.x = 1;
  }
  print() {
    console.log(this.x);
  }
}

class B extends A {
  constructor() {
    super();
    this.x = 2;
  }
  m() { super.print(); // this is equivalent to a.ptotype.print ()}}let b = new B();
b.m() // 2
Copy the code

In the code above, super.print() calls a.prototype.print (), but the this inside a.prototype.print () points to an instance of subclass B, resulting in 2 instead of 1. That is, super.print.call(this) is actually executed.

Note 3⚠️ : Assign via super

Since this refers to the subclass instance, if you assign a value to a property via super, which is this, the assigned property becomes the property of the subclass instance.

class A {
  constructor() {
    this.x = 1;
  }
}

class B extends A {
  constructor() { super(); this.x = 2; super.x = 3; // super is b console.log(super.x); X console.log(this.x); // undefined is used for a.prototype.x console.log(this.x); / / 3}}let b = new B();

Copy the code

Through these two pieces of code, we found a problem. When I evaluated by super, I took the property of the prototype of the parent class, but when I assigned by super, super referred to the instance of the child class.

To sum up:

From the above three chestnuts, we can see that when super is used as an object in ordinary methods:

  1. A subclass ofsuperA prototype object that points to a parent class, so methods or properties defined on an instance of the parent class, will not passsuperThe call.
  2. Passes in the subclass normal methodsuperWhen a method of a parent class is called, this inside the method points to the current subclass instance.
  3. Assigning a value to a property by super, in which case super is this, becomes the property of the subclass instance.

2.2 Super is applied as an object in static methods

If super is used as an object in a static method, then super refers to the parent class, not the parent class’s prototype object.

class Parent {
  static myMethod(msg) {
    console.log('static', msg);
  }

  myMethod(msg) {
    console.log('instance', msg); }} class Child extends Parent {static myMethod(MSG) {Parent super.mymethod (MSG); } myMethod(MSG) {Parent. Prototype super.mymethod (MSG); } } Child.myMethod(1); // static 1 var child = new Child(); child.myMethod(2); // instance 2Copy the code

In the code above, super refers to the parent class in static methods and to the parent class’s prototype object in normal methods.

Note 1 ⚠️

When a method of a parent class is called through super in a static method of a subclass, the this inside the method refers to the current subclass, not the instance of the subclass.

class A {
  constructor() {
    this.x = 1;
  }
  static print() {
    console.log(this.x);
  }
}

class B extends A {
  constructor() {
    super();
    this.x = 2;
  }
  static m() { super.print(); // this in a.int refers to the current subclass}} B.x = 3; B.m() // 3Copy the code

In the code above, in the static method B.m, super.print points to the static method of the parent class. This in this method refers to B, not an instance of B.

To sum up:

When a method of a parent class is called through super in a static method of a subclass, the this inside the method refers to the current subclass, not the instance of the subclass.

In a word

  1. superAs a function,super()That’s the parent constructorthisIs an instance of a class.
  2. superAs an object, in a normal methodsuper.The syntax refers to the parent class’s prototype object, used in static methodssuper.For syntax, look in the static method of the parent class. As for thethisPointing to the problem, remember one thing:If you have a method, plusstaticKeyword, indicating that the method is not inherited by the instance, but is called directly from the class, so in static methodsthisIt refers only to classes, not instances.