本人新手, 最近在看阮一峰老師的es6
里面class
的繼承這一章, 對(duì)super
一些概念不理解, 具體如下:
在阮一峰老師的博客里有這樣一段代碼:
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(this.x); // 3
}
}
let b = new B();
阮一峰老師是這么說的
由于this
指向子類實(shí)例,所以如果通過super
對(duì)某個(gè)屬性賦值,這時(shí)super
就是this
,賦值的屬性會(huì)變成子類實(shí)例的屬性。
上面代碼中,super.x
賦值為3
,這時(shí)等同于對(duì)this.x
賦值為3
這里我很不理解, 為什么使用super.x
進(jìn)行賦值以后就等同于this.x
,
我的理解是:
根據(jù)阮一峰老師前面說的
super
作為對(duì)象時(shí),在普通方法中,指向父類的原型對(duì)象
那么這里的super.x = 3
實(shí)際上應(yīng)該就是A.prototype.x = 3
, 那么對(duì)于子類B
應(yīng)該是沒有影響的, 所以個(gè)人理解結(jié)果應(yīng)該是2
但是瀏覽器跑出來的結(jié)果卻和阮老師的結(jié)果一樣是3
, 所以請(qǐng)問應(yīng)該如何理解
希望能有前輩給一個(gè)清晰的解答, 謝謝了!
由于this
指向子類實(shí)例,所以如果通過super
對(duì)某個(gè)屬性賦值,這時(shí)super
就是this
,賦值的屬性會(huì)變成子類實(shí)例的屬性。
上面代碼中,super.x
賦值為3
,這時(shí)等同于對(duì)this.x
賦值為3
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
console.log(super.x)// 如果上述成立 那么super.x=2 但是結(jié)果是undefined
super.x = 3;
console.log(this.x); // 3
}
}
let b = new B();
我并不理解super
的具體實(shí)現(xiàn),但是按照這邏輯加了一句代碼,結(jié)果顯然是不成立。弱弱的懷疑一下這不是通過現(xiàn)象反猜的吧?
前幾天剛好在學(xué)習(xí)這個(gè),看到文檔里得出3我也很疑惑,自己運(yùn)行了一下發(fā)現(xiàn)是等于2的,難道只有我一個(gè)人得出了2?
class A {
constructor() { // constructor方法默認(rèn)返回實(shí)例對(duì)象(即this)
this.x = 1; // 父類的實(shí)例屬性
console.log('子類B的實(shí)例:', this); // B?{x: 1},執(zhí)行兩次,因?yàn)橄旅鎴?zhí)行了super()兩次,返回的是子類B的實(shí)例。
}
foo() {
return 10;
}
}
console.log('父類的原型對(duì)象:', A.prototype); // {constructor: ?, foo: ?}。類的所有方法都定義在類的prototype屬性上面。
class B extends A {
constructor() {
super(); // 2. super使用的第一種情況,super作為函數(shù)調(diào)用時(shí),雖然代表了父類A的構(gòu)造函數(shù),但是返回的是子類B的實(shí)例。
console.log(super() === this); // 3. super返回的是子類的實(shí)例對(duì)象,this代表子類的實(shí)例對(duì)象,所以判斷它們相等返回true。
this.x = 2; // 1. this代表實(shí)例對(duì)象,就是下面new出來的實(shí)例對(duì)象b。(按照123的順序理解)
console.log('=====驗(yàn)證=====', this); // B?{x: 2}
// 題主主要問的是super當(dāng)做對(duì)象使用時(shí)的情況,super作為對(duì)象時(shí),在普通方法中,指向父類的原型對(duì)象。
console.log(super.foo()); // 10,相當(dāng)于A.prototype.foo()
// 由于super指向父類的原型對(duì)象,所以定義在父類實(shí)例上的方法或?qū)傩裕ㄒ簿褪歉割愔械膖his.x = 1),是無法通過super調(diào)用的。
console.log(super.x); // undefined,實(shí)際讀取的是A.prototype.x,所以返回undefined。
Object.defineProperty(A.prototype, 'x', { // 這里難道不是說明,執(zhí)行super.x = 3;的時(shí)候,實(shí)際就是執(zhí)行的A.prototype.x。
set(val) {
console.log(val) // 先輸出'測(cè)試',后輸出3。如果不是執(zhí)行的A.prototype.x,就不會(huì)進(jìn)到這里,不會(huì)有輸出。
}
});
super.x = '測(cè)試';
super.x = 3;
console.log('最終結(jié)果', this.x); // 最終結(jié)果 2
}
}
let b = new B();
console.log('=====驗(yàn)證=====', b); // B?{x: 2}
控制臺(tái):
個(gè)人理解和題主一樣,super指向的就是父類的原型對(duì)象,所以在super.x上賦值,不會(huì)影響到指向?qū)嵗龑?duì)象的this,所以應(yīng)該還是2,實(shí)際運(yùn)行結(jié)果也是2。
為什么有人得到2有人得到3,可能是es版本的原因,具體還需仔細(xì)研究,希望明白的大神不吝賜教。
題主看書看仔細(xì)些
第二種情況,super作為對(duì)象時(shí),在普通方法中,指向父類的原型對(duì)象;在靜態(tài)方法中,指向父類。
ES6 規(guī)定,在子類普通方法中通過super調(diào)用父類的方法時(shí),方法內(nèi)部的this指向當(dāng)前的子類實(shí)例。
這兩句話連在一起,不矛盾!意思就是:
意思是:
在子類普通方法中通過super調(diào)用父類的方法時(shí)
super
指向父類的原型對(duì)象,但是父類的方法中的this
指向當(dāng)前的子類實(shí)例。
super.x = 3;
這里super
指向父類的原型對(duì)象,沒錯(cuò)!
但是底層并不是直接執(zhí)行
A.prototype.x = 3
而是轉(zhuǎn)換了底層的this
,最終效果類似于:
this = 3
代碼驗(yàn)證:
class A {
constructor() {
this.x = 1
}
}
class B extends A {
constructor() {
super()
this.x = 2
Object.defineProperty(A.prototype, 'x', {
set: function(val) {
console.log(this, val)
//B {x: 2} 3,證明對(duì)super的賦值最終作用到了B {x: 2}身上,也就是新生成的實(shí)例,this
}
})
super.x = 3
console.log(this.x) // 3
}
}
let b = new B()
你再看看阮老師舉的函數(shù)調(diào)用的例子,這個(gè)例子就更清楚了,因?yàn)楹瘮?shù)可以用 call
代碼:
class A {
constructor() {
this.x = 1
}
print() {
console.log(this.x)
}
}
class B extends A {
constructor() {
super()
this.x = 2
}
m() {
// super.print()//上下兩句等價(jià)的,所以上面這句隱含轉(zhuǎn)換了this
super.print.call(this)
}
}
let b = new B()
b.m() // 2
super.print()
等價(jià)于super.print.call(this)
,因?yàn)榈讓与[含轉(zhuǎn)換了this
所以,最終有了下面的解釋:
由于this指向子類實(shí)例,所以如果通過super對(duì)某個(gè)屬性賦值,這時(shí)super就是this,賦值的屬性會(huì)變成子類實(shí)例的屬性。
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。