現在我希望有一個黑人,一樣具備 Person 的特性(名稱、年齡、打招呼),但要多一項技能是「唱 Rap」,這時候就應該利用「繼承」的方式來建立,而不是重新寫一個幾乎相同的 class
1 2 3 4 5 6 7 8
classBlackPersonextendsPerson{ rap() { console.log('yoyoyo my name is ' + this.name); } } const blackMan = new BlackPerson('blackMan', 30); blackMan.log(); // blackMan, 30 blackMan.rap(); // yoyoyo my name is blackMan
注意,這裡用了 extends 來繼承 Person 的資訊,所以即便 BlackPerson 中沒有寫 constructor,也一樣具備 name 和 age 這兩個屬性,而且也可以用 log 方法。
classBlackPersonextendsPerson{ constructor (gender) { // 加上一個新的 gender 屬性 this.gender = gender; } rap () { console.log('yoyoyo my name is ' + this.name + ', and my gender is ' + this.gender); } } // 建立 instance const blackMan = new BlackPerson('blackMan', 30, 'man'); // 預期:yoyoyo my name is blackMan, and my gender is man blackMan.rap();
但這樣會得到錯誤:
1 2
ReferenceError: Must call superconstructorinderivedclassbeforeaccessing 'this' orret urningfromderivedconstructor
簡單來說,要在繼承的 class 上設定 constructor 之前,得先呼叫 super 這個 function。先執行原本 Person 的 constructor,接著再執行 BlackPerson 的 constructor,所以應該要這樣寫:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classBlackPersonextendsPerson{ constructor (name, age, gender) { // 呼叫 super 並傳入參數 super(name, age); // super 執行完後才建立新的 gender this.gender = gender; } rap () { console.log('yoyoyo my name is ' + this.name + ', and my gender is ' + this.gender); } } // 建立 instance const blackMan = new BlackPerson('blackMan', 30, 'man'); // yoyoyo my name is blackMan, and my gender is man blackMan.rap();