淺談JavaScript原型鏈和寄生式繼承的實現(xiàn)

JavaScript原型鏈的問題在面試經常遇到 , 有時候我們很難搞懂其中的關系 ! 今天我們來談談 JavaScript 中 原型鏈的問題!

  1. 什么是原型?
    函數(shù)原型:
    在JavaScript中,函數(shù)不僅僅是一個可以重用的代碼塊疲酌,而且還可以作為一種數(shù)據使用拒课。在堆空間中為函數(shù)分配了它的存儲空間,函數(shù)名或函數(shù)的其他形式的引用保存了這個存儲空間的引用地址僻肖。所以JavaScript中的函數(shù)是一種引用數(shù)據類型卢鹦,這就是為什么我們說JavaScript中的函數(shù)也是對象。
    那么函數(shù)這樣的對象有很多特殊的性質揉稚,原型就是其中之一熬粗。每一個函數(shù)對象都包含一個屬性:prototype。當我們聲明一個函數(shù)時驻呐,函數(shù)對象就創(chuàng)建好了。而函數(shù)對象創(chuàng)建的同時猜拾,系統(tǒng)還會同時創(chuàng)建一個對象佣盒,并讓函數(shù)對象的prototype屬性指向它。
    比如說盯仪,當我們執(zhí)行下面代碼時:
    function Person ( perName,perAge ) { //… }
    就聲明了一個函數(shù)蜜葱,系統(tǒng)會將這個函數(shù)對象創(chuàng)建出來。內存中應該是這樣的情況:


    image.png

但是更深層次挖掘一下蚪燕,我還需要知道創(chuàng)建函數(shù)對象的同時奔浅,還會創(chuàng)建一個“原型對象”,由函數(shù)對象的prototype屬性指向這個原型對象

image.png

對象原型:
函數(shù)可以和以它為構造器所創(chuàng)建的所有對象共享原型對象鲁驶。就比如本文最初展示的代碼中舞骆,per01和per02都是Person函數(shù)創(chuàng)建的径荔,那么per01或per02就可以通過自身的proto屬性關聯(lián)到Person對象的原型脆霎。
下圖表示了它們之間的關系
image.png

所以函數(shù)的原型對象是可以為所有被創(chuàng)建對象共享的睛蛛,我們就可以將我們要為所有對象都添加的屬性添加到原型對象上, 從而實現(xiàn)寄生式繼承

function Person(perName,perAge,gender){
this.perName = perName;
this.perAge = perAge;
this.toString = function(){
return “PersonName=”+this.perName+” PersonAge=”+this.perAge;
};
}
var per01 = new Person(“Bob”, 20);
var per02 = new Person(“Kate”, 25);
Person.prototype.message = “Atguig is very good”;
console.log(per01.toString()+” message=”+per01.message);
console.log(per02.toString()+” message=”+per02.message);
//執(zhí)行結果:
//PersonName=Bob PersonAge=20 message=Atguig is very good
//PersonName=Kate PersonAge=25 message=Atguig is very good

JavaScript引擎在讀取per01對象的message屬性時先在當前對象本身的空間內查找,如果能找到則直接返回荸频,如果找不到則沿著proto屬性找到原型對象客冈,再在原型對象中查找message屬性。

  1. 什么是原型鏈
    在研究了對象原型和函數(shù)原型的關系后遇绞,我們還可以進一步深入思考:既然原型對象是一個“對象”燎窘,那么這個對象有沒有proto這個屬性呢?當然有褐健!
function Person(perName,perAge,gender){
this.perName = perName;
this.perAge = perAge;
this.toString = function(){
return “PersonName=”+this.perName+” PersonAge=”+this.perAge;
};
}
var person = new Person(“Tom”, 20, “male”);
console.log(person.__proto__);
console.log(person.__proto__.__proto__);
//執(zhí)行結果:
//Person {}
//Object {}

說明person.proto所指向的對象是由Person函數(shù)創(chuàng)建的蚜迅,而person.proto.proto所指向的對象是由Object函數(shù)創(chuàng)建的。
就對象的本質而言谁不,任何一個對象都是以new 構造器函數(shù)的方式創(chuàng)建的,所以所有對象都和構造器函數(shù)共享原型對象吵血。這樣說可能你會有疑問偷溺,我可以通過{屬性名:屬性值}的方式創(chuàng)建對象呀,這里并沒有用到構造器函數(shù)呀侦另?那么情看下面的代碼:

var obj = {“myName”:”Jerry”,”myAge”:15};
console.log(obj.constructor);
console.log(obj.__proto__ === Object.prototype);
//執(zhí)行結果:
//function Object()
//true

說明從本質上來說,任何對象的創(chuàng)建都依賴對應的構造器函數(shù)褒傅,當然也包含原型機制。既然如此霹菊,那么原型對象本身也是一個對象碌尔,這個對象也指向一個原型對象券敌,那么原型對象的原型對象也是對象,可以繼續(xù)指向一個原型對象……這就是原型鏈叹坦。


image.png

但原型鏈并不是無止境的卑雁,到Object()函數(shù)為止。

var obj = {“myName”:”Jerry”,”myAge”:15};
console.log(obj.__proto__.__proto__);
//執(zhí)行結果:
//null
  1. 如何快速理解原型鏈
    其實原型鏈理解起來不難, 我這里整理的一張圖 , 大家可以看看 僅供參考 !
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末莹捡,一起剝皮案震驚了整個濱河市扣甲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌启泣,老刑警劉巖示辈,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矾麻,死亡現(xiàn)場離奇詭異,居然都是意外死亡险耀,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門限次,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卖漫,“玉大人,你說我怎么就攤上這事羊始。” “怎么了突委?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵匀油,是天一觀的道長。 經常有香客問我敌蚜,道長,這世上最難降的妖魔是什么齐媒? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任喻括,我火速辦了婚禮贫奠,結果婚禮上,老公的妹妹穿的比我還像新娘叮阅。我一直安慰自己,他們只是感情好挑随,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布勒叠。 她就那樣靜靜地躺著,像睡著了一般眯分。 火紅的嫁衣襯著肌膚如雪拌汇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天弊决,我揣著相機與錄音噪舀,去河邊找鬼魁淳。 笑死,一個胖子當著我的面吹牛与倡,可吹牛的內容都是我干的界逛。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼纺座,長吁一口氣:“原來是場噩夢啊……” “哼息拜!你這毒婦竟也來了?” 一聲冷哼從身側響起净响,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤少欺,失蹤者是張志新(化名)和其女友劉穎馋贤,沒想到半個月后赞别,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡掸掸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年氯庆,在試婚紗的時候發(fā)現(xiàn)自己被綠了蹭秋。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扰付。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仁讨,靈堂內的尸體忽然破棺而出羽莺,到底是詐尸還是另有隱情,我是刑警寧澤洞豁,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布盐固,位于F島的核電站,受9級特大地震影響丈挟,放射性物質發(fā)生泄漏刁卜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一曙咽、第九天 我趴在偏房一處隱蔽的房頂上張望蛔趴。 院中可真熱鬧,春花似錦例朱、人聲如沸孝情。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箫荡。三九已至,卻和暖如春渔隶,著一層夾襖步出監(jiān)牢的瞬間羔挡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留婉弹,地道東北人睬魂。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像镀赌,于是被迫代替她去往敵國和親氯哮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351