幫你徹底搞懂JS中的prototype瓮增、__proto__與constructor(圖解)

本文基于谷歌瀏覽器(版本 72.0.3626.121)的實驗結(jié)果所得功咒。

我們從如下一個簡單的例子展開討論,并配以相關(guān)的圖幫助理解:

function Foo() {...};
let f1 = new Foo();

以上代碼表示創(chuàng)建一個構(gòu)造函數(shù)Foo()桦踊,并用new關(guān)鍵字實例化該構(gòu)造函數(shù)得到一個實例化對象f1椅野。雖然是簡簡單單的兩行代碼,然而它們背后的關(guān)系卻是錯綜復(fù)雜的籍胯,如下圖所示:



看到這圖別怕竟闪,讓我們一步步剖析,徹底搞懂它們杖狼!

圖的說明:右下角為圖例瘫怜,紅色箭頭表示__proto__屬性指向、綠色箭頭表示prototype屬性的指向本刽、棕色實線箭頭表示本身具有的constructor屬性的指向,棕色虛線箭頭表示繼承而來的constructor屬性的指向赠涮;藍色方塊表示對象子寓,淺綠色方塊表示函數(shù)(這里為了更好看清,F(xiàn)oo()僅代表是函數(shù)笋除,并不是指執(zhí)行函數(shù)Foo后得到的結(jié)果斜友,圖中的其他函數(shù)同理)。圖的中間部分即為它們之間的聯(lián)系垃它,圖的最左邊即為例子代碼鲜屏。

首先烹看,我們需要牢記兩點:①__proto__和constructor屬性是對象所獨有的;prototype屬性是函數(shù)所獨有的洛史。但是由于JS中函數(shù)也是一種對象惯殊,所以函數(shù)也擁有__proto__和constructor屬性,這點是致使我們產(chǎn)生困惑的很大原因之一也殖。上圖有點復(fù)雜土思,我們把它按照屬性分別拆開,然后進行分析:

proto

第一忆嗜,這里我們僅留下 __proto__屬性己儒,它是對象所獨有的,可以看到__proto__屬性都是由一個對象指向一個對象捆毫,即指向它們的原型對象(也可以理解為父對象)闪湾,那么這個屬性的作用是什么呢?它的作用就是當(dāng)訪問一個對象的屬性時绩卤,如果該對象內(nèi)部不存在這個屬性途样,那么就會去它的\_\_proto\_\_屬性所指向的那個對象(可以理解為父對象)里找,如果父對象也不存在這個屬性省艳,則繼續(xù)往父對象的\_\_proto\_\_屬性所指向的那個對象(可以理解為爺爺對象)里找娘纷,如果還沒找到,則繼續(xù)往上找…直到原型鏈頂端null跋炕,此時若還沒找到赖晶,則返回undefined,由以上這種通過__proto__屬性來連接對象直到null的一條鏈即為我們所謂的原型鏈辐烂。

prototype

第二遏插,接下來我們看 prototype 屬性:


prototype屬性,別忘了一點纠修,就是我們前面提到要牢記的兩點中的第二點胳嘲,它是函數(shù)所獨有的,它是從一個函數(shù)指向一個對象扣草。它的含義是函數(shù)的原型對象了牛,也就是這個函數(shù)(其實所有函數(shù)都可以作為構(gòu)造函數(shù))所創(chuàng)建的實例的原型對象,由此可知:f1.__proto__ === Foo.prototype辰妙,它們兩個完全一樣鹰祸。那prototype屬性的作用又是什么呢?它的作用就是包含可以由特定類型的所有實例共享的屬性和方法密浑,也就是讓該函數(shù)所實例化的對象們都可以找到公用的屬性和方法蛙婴。任何函數(shù)在創(chuàng)建的時候,其實會默認同時創(chuàng)建該函數(shù)的prototype對象尔破。

constructor

最后街图,我們來看一下 constructor 屬性:


constructor屬性也是對象才擁有的浇衬,它是從一個對象指向一個函數(shù),含義就是指向該對象的構(gòu)造函數(shù)餐济,每個對象都有構(gòu)造函數(shù)(本身擁有或繼承而來耘擂,繼承而來的要結(jié)合__proto__屬性查看會更清楚點,如下圖所示)颤介,從上圖中可以看出Function這個對象比較特殊梳星,它的構(gòu)造函數(shù)就是它自己(因為Function可以看成是一個函數(shù),也可以是一個對象)滚朵,所有函數(shù)和對象最終都是由Function構(gòu)造函數(shù)得來冤灾,所以constructor屬性的終點就是Function這個函數(shù)。


這里解釋一下上段中“每個對象都有構(gòu)造函數(shù)”這句話辕近。這里的意思是每個對象都可以找到其對應(yīng)的constructor韵吨,因為創(chuàng)建對象的前提是需要有constructor,而這個constructor可能是對象自己本身顯式定義的或者通過__proto__在原型鏈中找到的移宅。而單從constructor這個屬性來講归粉,只有prototype對象才有。每個函數(shù)在創(chuàng)建的時候漏峰,JS會同時創(chuàng)建一個該函數(shù)對應(yīng)的prototype對象糠悼,而函數(shù)創(chuàng)建的對象.__proto__ === 該函數(shù).prototype,該函數(shù).prototype.constructor===該函數(shù)本身浅乔,故通過函數(shù)創(chuàng)建的對象即使自己沒有constructor屬性倔喂,它也能通過__proto__找到對應(yīng)的constructor,所以任何對象最終都可以找到其構(gòu)造函數(shù)(null如果當(dāng)成對象的話靖苇,將null除外)席噩。如下:

總結(jié)一下:

  1. 我們需要牢記兩點:①__proto__和constructor屬性是對象所獨有的;② prototype屬性是函數(shù)所獨有的贤壁,因為函數(shù)也是一種對象悼枢,所以函數(shù)也擁有__proto__和constructor屬性。
  2. __proto__屬性的作用就是當(dāng)訪問一個對象的屬性時脾拆,如果該對象內(nèi)部不存在這個屬性馒索,那么就會去它的__proto__屬性所指向的那個對象(父對象)里找,一直找名船,直到__proto__屬性的終點null绰上,然后返回undefined,通過__proto__屬性將對象連接起來的這條鏈路即我們所謂的原型鏈包帚。
  3. prototype屬性的作用就是讓該函數(shù)所實例化的對象們都可以找到公用的屬性和方法,即f1.__proto__ === Foo.prototype运吓。
  4. constructor屬性的含義就是指向該對象的構(gòu)造函數(shù)渴邦,所有函數(shù)(此時看成對象了)最終的構(gòu)造函數(shù)都指向Function疯趟。

原文:幫你徹底搞懂JS中的prototype、__proto__與constructor(圖解)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谋梭,一起剝皮案震驚了整個濱河市信峻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓮床,老刑警劉巖盹舞,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異隘庄,居然都是意外死亡踢步,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門丑掺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來获印,“玉大人,你說我怎么就攤上這事街州〖娣幔” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵唆缴,是天一觀的道長鳍征。 經(jīng)常有香客問我,道長面徽,這世上最難降的妖魔是什么艳丛? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮斗忌,結(jié)果婚禮上质礼,老公的妹妹穿的比我還像新娘。我一直安慰自己织阳,他們只是感情好眶蕉,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著唧躲,像睡著了一般造挽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弄痹,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天饭入,我揣著相機與錄音,去河邊找鬼肛真。 笑死谐丢,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乾忱,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼讥珍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了窄瘟?” 一聲冷哼從身側(cè)響起衷佃,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹄葱,沒想到半個月后氏义,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡图云,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年惯悠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琼稻。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡吮螺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出帕翻,到底是詐尸還是另有隱情鸠补,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布嘀掸,位于F島的核電站紫岩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏睬塌。R本人自食惡果不足惜泉蝌,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望揩晴。 院中可真熱鬧勋陪,春花似錦、人聲如沸硫兰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劫映。三九已至违孝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泳赋,已是汗流浹背雌桑。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留祖今,地道東北人校坑。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓拣技,卻偏偏與公主長得像,于是被迫代替她去往敵國和親耍目。 傳聞我的和親對象是個殘疾皇子过咬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

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