ES6的 super 关键字
Class之間可以通過extends關(guān)鍵字實現(xiàn)繼承,這比ES5的通過修改原型鏈實現(xiàn)繼承,要清晰和方便很多。
子類必須在constructor方法中調(diào)用super方法,否則新建實例時會報錯。
這是因為子類沒有自己的this對象,而是繼承父類的this對象,然后對其進行加工。如果不調(diào)用super方法,子類就得不到this對象。ES5的繼承,實質(zhì)是先創(chuàng)造子類的實例對象this,然后再將父類的方法添加到this上面(Parent.apply(this))。ES6的繼承機制完全不同,實質(zhì)是先創(chuàng)造父類的實例對象this(所以必須先調(diào)用super方法),然后再用子類的構(gòu)造函數(shù)修改this。
在子類的構(gòu)造函數(shù)中,只有調(diào)用super之后,才可以使用this關(guān)鍵字,否則會報錯。這是因為子類實例的構(gòu)建,是基于對父類實例加工,只有super方法才能返回父類實例。
類的prototype屬性和proto屬性
大多數(shù)瀏覽器的ES5實現(xiàn)之中,每一個對象都有proto屬性,指向?qū)?yīng)的構(gòu)造函數(shù)的prototype屬性。Class作為構(gòu)造函數(shù)的語法糖,同時有prototype屬性和proto屬性,因此同時存在兩條繼承鏈。
1)子類的proto屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。
2)子類prototype屬性的proto屬性,表示方法的繼承,總是指向父類的prototype屬性。
Object.getPrototypeOf()
Object.getPrototypeOf方法可以用來從子類上獲取父類。可以使用這個方法判斷,一個類是否繼承了另一個類。
Class的取值函數(shù)(getter)和存值函數(shù)(setter)
與ES5一樣,在Class內(nèi)部可以使用get和set關(guān)鍵字,對某個屬性設(shè)置存值函數(shù)和取值函數(shù),攔截該屬性的存取行為。
Class不存在變量提升(hoist),這一點與ES5完全不同。
Class立即執(zhí)行表達式
采用Class表達式,可以寫出立即執(zhí)行的Class。
let person = new class {constructor(name) {this.name = name; //類的方法內(nèi)部如果含有this,它默認指向類的實例}sayName() {console.log(this.name);} }('張三'); person.sayName(); // "張三" 復(fù)制代碼super關(guān)鍵字:
super這個關(guān)鍵字,既可以當作函數(shù)使用,也可以當作對象使用。在這兩種情況下,它的用法完全不同。
1) super作為函數(shù)調(diào)用時,代表父類的構(gòu)造函數(shù)。ES6 要求,子類的構(gòu)造函數(shù)必須執(zhí)行一次super函數(shù)。
注意,super雖然代表了父類A的構(gòu)造函數(shù),但是返回的是子類B的實例,即super內(nèi)部的this指的是B,因此super()在這里相當于
A.prototype.constructor.call(this)。2) super作為對象時,在普通方法中,指向父類的原型對象;在靜態(tài)方法中,指向父類。
class A {p() {return 2;} } class B extends A {constructor() {super();console.log(super.p()); // 2//super.p() 相當于 A.prototype.p()} } let b = new B();復(fù)制代碼由于super指向父類的原型對象,所以定義在父類實例上的方法或?qū)傩?#xff0c;是無法通過super調(diào)用的。
如果屬性定義在父類的原型對象上,super就可以取到。
ES6 規(guī)定,通過super調(diào)用父類的方法時,super會綁定子類的this。
class A {constructor() {this.x = 1;}print() {console.log(this.x);} } class B extends A {constructor() {super();this.x = 2;}m() {super.print();} } let b = new B(); b.m() // 2復(fù)制代碼上面代碼中,super.print()雖然調(diào)用的是A.prototype.print(),但是A.prototype.print()會綁定子類B的this,導(dǎo)致輸出的是2,而不是1。也就是說,實際上執(zhí)行的是super.print.call(this)。
總結(jié)
以上是生活随笔為你收集整理的ES6的 super 关键字的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转]LIB和DLL的区别与使用
- 下一篇: Spring Boot中验证码实现kap