收藏整理了ES6 Class 中的 super 關鍵字,本文將分享給大家,非常不錯,具有參考借鑒價值,需要的朋友參考下吧,希望能幫助到大家。
以下只是個人的學習筆記:
super這個關鍵字,既可以當作函數使用,也可以當作物件使用。在這兩種情況下,它的用法完全不同。
1、當作函數使用
class A {} class B extends A { constructor() { super(); //ES6 要求,子类的构造函数必须执行一次super函数。 } }
注意,super雖然代表了父類別A的建構函數,但是傳回的是子類別B的實例,即super內部的this指的是B,因此super()在這裡相當於A.prototype.constructor.call(this)。
class A { constructor() { console.log(new.target.name); //new.target指向当前正在执行的函数 } } class B extends A { constructor() { super(); } } new A() // A new B() // B
可以看到,在super()執行時,它指向的是子類別B的建構函數,而不是父類別A的建構子。也就是說,super()內部的this指向的是B。
2、當作物件使用
在普通方法中,指向父類別的原型物件;在靜態方法中,指向父類別。
class A { c() { return 2; } } class B extends A { constructor() { super(); console.log(super.c()); // 2 } } let b = new B();
上面程式碼中,子類別B當中的super.c(),就是將super當作一個物件使用。這時,super在普通方法之中,指向A.prototype,所以super.c()就相當於A.prototype.c()。
透過super呼叫父類別的方法時,super會綁定子類別的this。
class A { constructor() { this.x = 1; } s() { console.log(this.x); } } class B extends A { constructor() { super(); this.x = 2; } m() { super.s(); } } let b = new B(); b.m() // 2
上面程式碼中,super.s()雖然呼叫的是A.prototype.s(),但是A.prototype.s()會綁定子類B的this,導致輸出的是2,而不是1。也就是說,實際上執行的是super.s.call(this)。
由於綁定子類別的this,所以如果透過super對某個屬性賦值,這時super就是this,賦值的屬性會變成子類別實例的屬性。
class A { constructor() { this.x = 1; } } class B extends A { constructor() { super(); this.x = 2; super.x = 3; console.log(super.x); // undefined console.log(this.x); // 3 } } let b = new B();
上面程式碼中,super.x賦值為3,這時等同於對this.x賦值為3。而當讀取super.x的時候,讀的是A.prototype.x,所以回傳undefined。
注意,使用super的時候,必須明確指定是作為函數、還是物件使用,否則會報錯。
class A {} class B extends A { constructor() { super(); console.log(super); // 报错 } }
上面程式碼中,console.log(super)當中的super,無法看出是作為函數使用,還是作為物件使用,所以JavaScript 引擎解析程式碼的時候就會報錯。這時,如果能清楚顯示super的資料類型,就不會報錯。
最後,由於物件總是繼承其他物件的,所以可以在任一個物件中,使用super關鍵字。
相關推薦:
詳解Laravel實作supervisor執行非同步進程的方法
#以上是ES6 Class 中的 super 關鍵字詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!