【每日一題NO.52】ES6 類繼承中 super 的作用

人生苦短,總需要一點(diǎn)儀式感。比如學(xué)前端~
概念
super 當(dāng)作函數(shù)
super 當(dāng)做對(duì)象
普通方法中指向父類的原型對(duì)象
靜態(tài)方法中指向父類本身
super中的this指向(總結(jié))
概念
super 關(guān)鍵詞用于訪問和調(diào)用一個(gè)對(duì)象的父對(duì)象上的函數(shù)。
super 既可以當(dāng)做函數(shù)使用,也可以當(dāng)做對(duì)象使用
super([arguments]);?//?調(diào)用父對(duì)象/父類?的構(gòu)造函數(shù)
super.functionOnParent([arguments]);?//調(diào)用?父對(duì)象/父類?上的方法
super 當(dāng)作函數(shù)
super 作為函數(shù)調(diào)用時(shí),代表父類的構(gòu)造函數(shù)。
ES6 要求,子類的構(gòu)造函數(shù)必須執(zhí)行一次 super 函數(shù)
class?Father?{}
class?Son?extends?Father?{
??constructor()?{
????super();?//?子類實(shí)現(xiàn)繼承時(shí),構(gòu)造函數(shù)必須寫super函數(shù)調(diào)用
??}
}
super代表父類的構(gòu)造函數(shù) 被調(diào)用時(shí),有以下幾點(diǎn)需要注意:
super 返回的對(duì)象是子類的實(shí)例。super 內(nèi)部的 this 指的是 Son 的實(shí)例,這里調(diào)用 super()相當(dāng)于Father.prototype.constructor.call(this)這么寫。super 作為構(gòu)造函數(shù)時(shí),必須在使用 this 關(guān)鍵詞之前使用,否則會(huì)報(bào)錯(cuò) super()調(diào)用,只能用在子類構(gòu)造函數(shù)中,用在其他地方會(huì)報(bào)錯(cuò)
super 當(dāng)做對(duì)象
super 作為對(duì)象時(shí),有兩種情況:
在普通方法中,指向父類的原型對(duì)象; 在靜態(tài)方法中,指向父類本身
普通方法中指向父類的原型對(duì)象
super 指向的是父類原型對(duì)象,能獲取父類原型對(duì)象上面的屬性和方法,不能獲取父類實(shí)例上的屬性和方法 通過 super 調(diào)用父類原型對(duì)象上的方法時(shí),父類原型對(duì)象上方法內(nèi)部的 this 指向子類實(shí)例
class?Father?{
??constructor()?{
????this.name?=?"fatherName";
??}
??print()?{
????console.log(this.name);?//?代表父類構(gòu)造函數(shù)使用的super(),函數(shù)內(nèi)部的this指向子類實(shí)例
??}
}
class?Son?extends?Father?{
??constructor()?{
????super();
????this.name?=?"sonName";
??}
??printSon()?{
????super.print();?//?print內(nèi)部this指向Son的實(shí)例化對(duì)象
??}
}
let?son?=?new?Son();
son.printSon();?//'sonName'
/*?解析
Son.printSon函數(shù)中,super.print()?雖然相當(dāng)于調(diào)用的是“Father.prototype.print()”,
但是Father.prototype.print()內(nèi)部的 this 指向子類 Son 的實(shí)例,所以實(shí)際輸出的是“sonName”而不是“fatherName”。
也就是說,printSon函數(shù)內(nèi)實(shí)際上執(zhí)行的是“super.print.call(this)”。
*/
通過 super 來對(duì)某個(gè)屬性賦值,這時(shí) super 就是 子類this,賦值的屬性會(huì)變?yōu)樽宇悓?shí)例son的屬性
//?阮一峰?es6文檔的例子
class?A?{
??constructor()?{
????this.x?=?1;
??}
}
class?B?extends?A?{
??constructor()?{
????super();
????this.x?=?2;
????super.x?=?3;?//?相當(dāng)于?this.x?=?3
????console.log(super.x);?//?undefined?父類沒有增加x屬性
????console.log(this.x);?//?3?子類的x屬性被改變
??}
}
let?b?=?new?B();
console.log(b.x);?//?3
靜態(tài)方法中指向父類本身
因?yàn)樵陟o態(tài)方法中使用就跟原型沒關(guān)系了,所以不代表原型也不代表實(shí)例對(duì)象。
在靜態(tài)方法中,super 對(duì)象指的是父類,而不是父類的原型對(duì)象 在靜態(tài)方法中,super函數(shù)內(nèi)部的this指向的是子類,而不是子類實(shí)例
//?阮一峰?es6文檔的例子
class?Parent?{
??static?myMethod(msg)?{?//?代號(hào):1 靜態(tài)方法, 會(huì)被3調(diào)用
????console.log("static",?msg,?this);
??}
??myMethod(msg)?{?//?代號(hào):2 原型方法,會(huì)被4調(diào)用
????console.log("instance",?msg,?this);
??}
}
class?Child?extends?Parent?{
??static?myMethod(msg)?{?//?代號(hào)3:?靜態(tài)方法
????super.myMethod(msg);?//?super代表父類,這樣寫,相當(dāng)于?Parent.static?myMethod.call(Child)
??}
??myMethod(msg)?{?//?代號(hào):4 原型方法
????super.myMethod(msg);?//?super代表父類的原型對(duì)象,這樣寫,相當(dāng)于?Parent.prototype.myMethod.call(this)
??}
}
Child.myMethod('類對(duì)象-調(diào)用靜態(tài)方法');?//?類,調(diào)用靜態(tài)方法3
var?child?=?new?Child();
child.myMethod('實(shí)例對(duì)象-調(diào)用原型方法');?//?實(shí)例化對(duì)象,調(diào)用原型方法4

super中的this指向(總結(jié))
代表父類構(gòu)造函數(shù)使用的 super(),函數(shù)內(nèi)部的this指向子類實(shí)例在普通方法中,代表父類原型對(duì)象使用的super,函數(shù)內(nèi)部this指向子類實(shí)例 在靜態(tài)方法中,代表父類使用的super,函數(shù)內(nèi)部this指向子類【就他特殊,單獨(dú)記憶】
小小提示:使用super的時(shí)候,必須顯式指定是作為函數(shù)還是作為對(duì)象使用,否則會(huì)報(bào)錯(cuò)。
所有《每日一題》的 知識(shí)大綱索引腦圖 整理在此:https://www.yuque.com/dfe_evernote/interview/everyday
你也可以點(diǎn)擊文末的 “閱讀原文” 快速跳轉(zhuǎn)

評(píng)論
圖片
表情
