1. 程式人生 > >ES6 Class繼承中super在不同場景中的用法

ES6 Class繼承中super在不同場景中的用法

super這個關鍵字,既可以當作函式使用,也可以當作物件使用。在這兩種情況下,它的用法完全不同。

第一種情況,super作為函式呼叫時,代表父類的建構函式。ES6 要求,子類的建構函式必須執行一次super函式。

class A {}

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

上面程式碼中,子類B的建構函式之中的super(),代表呼叫父類的建構函式。這是必須的,否則 JavaScript 引擎會報錯。

注意,super雖然代表了父類A的建構函式,但是返回的是子類B的例項,即super內部的this指的是B,因此super()在這裡相當於A.prototype.constructor.call(this)。

第二種情況,super作為物件時,在普通方法中,指向父類的原型物件;在靜態方法中,指向父類。
例1:普通方法

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

class B extends A {
  constructor() {
    super();
    console.log(super.p()); // 2
  }
}

let b = new B();

上面程式碼中,子類B當中的super.p(),就是將super當作一個物件使用。這時,super在普通方法之中,指向A.prototype,所以super.p()就相當於A.prototype.p()。

這裡需要注意,由於super指向父類的原型物件,所以定義在父類例項上的方法或屬性,是無法通過super呼叫的。

如果super作為物件,用在靜態方法之中,這時super將指向父類,而不是父類的原型物件。
例2:靜態方法

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

  myMethod(msg) {
    console.log('instance', msg);
  }
}

class Child extends Parent {
  static myMethod(msg) {
    super
.myMethod(msg); } myMethod(msg) { super.myMethod(msg); } } Child.myMethod(1); // static 1 var child = new Child(); child.myMethod(2); // instance 2

–參考自阮一峰《ES6