super這個關鍵字,既能夠看成函數使用,也能夠看成對象使用。在這兩種狀況下,它的用法徹底不一樣。es6
第一種狀況,super做爲函數調用時,表明父類的構造函數。ES6 要求,子類的構造函數必須執行一次super函數。markdown
class A {} class B extends A { constructor() { super(); } }
上面代碼中,子類B的構造函數之中的super(),表明調用父類的構造函數。這是必須的,不然 JavaScript 引擎會報錯。函數
注意,super雖然表明了父類A的構造函數,可是返回的是子類B的實例,即super內部的this指的是B,所以super()在這裏至關於A.prototype.constructor.call(this)。this
第二種狀況,super做爲對象時,在普通方法中,指向父類的原型對象;在靜態方法中,指向父類。
例1:普通方法spa
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()。prototype
這裏須要注意,因爲super指向父類的原型對象,因此定義在父類實例上的方法或屬性,是沒法經過super調用的。code
若是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》ip