面向?qū)ο笾玩溊^承(一)

一. 原型與構(gòu)造函數(shù)

Js所有的函數(shù)都有一個prototype屬性,這個屬性引用了一個對象,即原型對象深员,也簡稱原型。這個函數(shù)包括構(gòu)造函數(shù)和普通函數(shù)蛙埂,我們講的更多是構(gòu)造函數(shù)的原型倦畅,但是也不能否定普通函數(shù)也有原型。譬如普通函數(shù):

functionF(){

;

}

alert(F.prototypeinstanceofObject)//true

構(gòu)造函數(shù)绣的,也即構(gòu)造對象叠赐。首先了解下通過構(gòu)造函數(shù)實(shí)例化對象的過程欲账。

functionA(x){

this.x=x;

}

varobj=newA(1);

實(shí)例化obj對象有三步:

1. 創(chuàng)建obj對象:obj=new Object();

2. 將obj的內(nèi)部__proto__指向構(gòu)造他的函數(shù)A的prototype,同時芭概,obj.constructor===A.prototype.constructor(這個是永遠(yuǎn)成立的赛不,即使A.prototype不再指向原來的A原型,也就是說:類的實(shí)例對象的constructor屬性永遠(yuǎn)指向"構(gòu)造函數(shù)"的prototype.constructor)罢洲,從而使得obj.constructor.prototype指向A.prototype(obj.constructor.prototype===A.prototype踢故,當(dāng)A.prototype改變時則不成立,下文有遇到)惹苗。obj.constructor.prototype與的內(nèi)部_proto_是兩碼事殿较,實(shí)例化對象時用的是_proto_,obj是沒有prototype屬性的桩蓉,但是有內(nèi)部的__proto__淋纲,通過__proto__來取得原型鏈上的原型屬性和原型方法,F(xiàn)ireFox公開了__proto__院究,可以在FireFox中alert(obj.__proto__)洽瞬;

3. 將obj作為this去調(diào)用構(gòu)造函數(shù)A,從而設(shè)置成員(即對象屬性和對象方法)并初始化业汰。

當(dāng)這3步完成伙窃,這個obj對象就與構(gòu)造函數(shù)A再無聯(lián)系,這個時候即使構(gòu)造函數(shù)A再加任何成員样漆,都不再影響已經(jīng)實(shí)例化的obj對象了对供。此時,obj對象具有了x屬性氛濒,同時具有了構(gòu)造函數(shù)A的原型對象的所有成員,當(dāng)然鹅髓,此時該原型對象是沒有成員的舞竿。

原型對象初始是空的,也就是沒有一個成員(即原型屬性和原型方法)窿冯∑保可以通過如下方法驗(yàn)證原型對象具有多少成員。

varnum=0;

for(oinA.prototype) {

alert(o);//alert出原型屬性名字

num++;

}

alert("member:"+num);//alert出原型所有成員個數(shù)醒串。

但是执桌,一旦定義了原型屬性或原型方法,則所有通過該構(gòu)造函數(shù)實(shí)例化出來的所有對象芜赌,都繼承了這些原型屬性和原型方法仰挣,這是通過內(nèi)部的_proto_鏈來實(shí)現(xiàn)的。

譬如

A.prototype.say=function(){alert("Hi")};

那所有的A的對象都具有了say方法缠沈,這個原型對象的say方法是唯一的副本給大家共享的膘壶,而不是每一個對象都有關(guān)于say方法的一個副本错蝴。

二. 原型與繼承

首先,看個簡單的繼承實(shí)現(xiàn)颓芭。

1顷锰。functionA(x){

2。this.x=x;

3亡问。}

4官紫。functionB(x,y){

5。this.tmpObj=A;

6州藕。this.tmpObj(x);

7束世。deletethis.tmpObj;

8。this.y=y;

9慎框。}

第5良狈、6、7行:創(chuàng)建臨時屬性tmpObj引用構(gòu)造函數(shù)A笨枯,然后在B內(nèi)部執(zhí)行薪丁,執(zhí)行完后刪除。當(dāng)在B內(nèi)部執(zhí)行了this.x=x后(這里的this是B的對象)馅精,B當(dāng)然就擁有了x屬性严嗜,當(dāng)然B的x屬性和A的x屬性兩者是獨(dú)立,所以并不能算嚴(yán)格的繼承洲敢。第5漫玄、6、7行有更簡單的實(shí)現(xiàn),就是通過call(apply)方法:A.call(this,x);

這兩種方法都有將this傳遞到A的執(zhí)行里,this指向的是B的對象扳肛,這就是為什么不直接A(x)的原因谅畅。這種繼承方式即是類繼承(js沒有類,這里只是指構(gòu)造函數(shù)),雖然繼承了A構(gòu)造對象的所有屬性方法,但是不能繼承A的原型對象的成員。而要實(shí)現(xiàn)這個目的隐孽,就是在此基礎(chǔ)上再添加原型繼承。

通過下面的例子健蕊,就能很深入地了解原型菱阵,以及原型參與實(shí)現(xiàn)的完美繼承。(本文核心在此^_^)

1functionA(x){

2this.x=x;

3}

4A.prototype.a="a";

5functionB(x,y){

6this.y=y;

7A.call(this,x);

8}

9B.prototype.b1=function(){

10alert("b1");

11}

12B.prototype=newA();

13B.prototype.b2=function(){

14alert("b2");

15}

16B.prototype.constructor=B;

17varobj=newB(1,3);

這個例子講的就是B繼承A缩功。第7行類繼承:A.call(this.x);上面已講過晴及。實(shí)現(xiàn)原型繼承的是第12行:B.prototype=newA();

就是說把B的原型指向了A的1個實(shí)例對象,這個實(shí)例對象具有x屬性嫡锌,為undefined抗俄,還具有a屬性脆丁,值為"a"。所以B原型也具有了這2個屬性(或者說动雹,B和A建立了原型鏈槽卫,B是A的下級)。而因?yàn)榉讲诺念惱^承胰蝠,B的實(shí)例對象也具有了x屬性歼培,也就是說obj對象有2個同名的x屬性,此時原型屬性x要讓位于實(shí)例對象屬性x茸塞,所以obj.x是1躲庄,而非undefined。第13行又定義了原型方法b2钾虐,所以B原型也具有了b2噪窘。雖然第9~11行設(shè)置了原型方法b1,但是你會發(fā)現(xiàn)第12行執(zhí)行后效扫,B原型不再具有b1方法倔监,也就是obj.b1是undefined。因?yàn)榈?2行使得B原型指向改變菌仁,原來具有b1的原型對象被拋棄浩习,自然就沒有b1了。

第12行執(zhí)行完后济丘,B原型(B.prototype)指向了A的實(shí)例對象谱秽,而A的實(shí)例對象的構(gòu)造器是構(gòu)造函數(shù)A,所以B.prototype.constructor就是構(gòu)造對象A了(換句話說摹迷,A構(gòu)造了B的原型)疟赊。

alert(B.prototype.constructor)出來后就是"function A(x){...}" 。同樣地峡碉,obj.constructor也是A構(gòu)造對象听绳,alert(obj.constructor)出來后就是"function A(x){...}" ,也就是說B.prototype.constructor===obj.constructor(true)异赫,但是B.prototype===obj.constructor.prototype(false),因?yàn)榍罢呤荁的原型头岔,具有成員:x,a,b2塔拳,后者是A的原型,具有成員:a峡竣。如何修正這個問題呢靠抑,就在第16行,將B原型的構(gòu)造器重新指向了B構(gòu)造函數(shù)适掰,那么B.prototype===obj.constructor.prototype(true)颂碧,都具有成員:x,a,b2荠列。

如果沒有第16行,那是不是obj = new B(1,3)會去調(diào)用A構(gòu)造函數(shù)實(shí)例化呢载城?答案是否定的肌似,你會發(fā)現(xiàn)obj.y=3,所以仍然是調(diào)用的B構(gòu)造函數(shù)實(shí)例化的诉瓦。雖然obj.constructor===A(true)川队,但是對于new B()的行為來說,執(zhí)行了上面所說的通過構(gòu)造函數(shù)創(chuàng)建實(shí)例對象的3個步驟睬澡,第一步固额,創(chuàng)建空對象;第二步煞聪,obj.__proto__ === B.prototype斗躏,B.prototype是具有x,a,b2成員的,obj.constructor指向了B.prototype.constructor昔脯,即構(gòu)造函數(shù)A啄糙;第三步,調(diào)用的構(gòu)造函數(shù)B去設(shè)置和初始化成員栅干,具有了屬性x,y迈套。雖然不加16行不影響obj的屬性,但如上一段說碱鳞,卻影響obj.constructor和obj.constructor.prototype桑李。所以在使用了原型繼承后,要進(jìn)行修正的操作窿给。

關(guān)于第12贵白、16行,總言之崩泡,第12行使得B原型繼承了A的原型對象的所有成員禁荒,但是也使得B的實(shí)例對象的構(gòu)造器的原型指向了A原型,所以要通過第16行修正這個缺陷角撞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呛伴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谒所,更是在濱河造成了極大的恐慌热康,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劣领,死亡現(xiàn)場離奇詭異姐军,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門奕锌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來著觉,“玉大人,你說我怎么就攤上這事惊暴”穑” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵缴守,是天一觀的道長葬毫。 經(jīng)常有香客問我,道長屡穗,這世上最難降的妖魔是什么贴捡? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮村砂,結(jié)果婚禮上烂斋,老公的妹妹穿的比我還像新娘。我一直安慰自己础废,他們只是感情好汛骂,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著评腺,像睡著了一般帘瞭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蒿讥,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天蝶念,我揣著相機(jī)與錄音,去河邊找鬼芋绸。 笑死媒殉,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的摔敛。 我是一名探鬼主播廷蓉,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼马昙!你這毒婦竟也來了桃犬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤行楞,失蹤者是張志新(化名)和其女友劉穎攒暇,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體敢伸,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年恒削,在試婚紗的時候發(fā)現(xiàn)自己被綠了池颈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尾序。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖躯砰,靈堂內(nèi)的尸體忽然破棺而出每币,到底是詐尸還是另有隱情,我是刑警寧澤琢歇,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布兰怠,位于F島的核電站,受9級特大地震影響李茫,放射性物質(zhì)發(fā)生泄漏揭保。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一魄宏、第九天 我趴在偏房一處隱蔽的房頂上張望秸侣。 院中可真熱鬧,春花似錦宠互、人聲如沸味榛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搏色。三九已至,卻和暖如春券册,著一層夾襖步出監(jiān)牢的瞬間频轿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工汁掠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留略吨,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓考阱,卻偏偏與公主長得像翠忠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子乞榨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容