深入理解JavaScript的原型與原型鏈(繼承)

原型的基本概念


要想真正理解js的原型和原型鏈的概念沟蔑,必須且只要記住以下幾點(diǎn)即可:

? 一切都是對象(看似如此)秦爆。

undefined, number, string, boolean四種屬于簡單的值類型唇聘,不是對象懈词,使用基本類型變量可以調(diào)用方法是因?yàn)楫a(chǎn)生了包裝對象(臨時(shí)的)童叠。剩下的幾種情況——函數(shù)慎菲、數(shù)組嫁蛇、對象、null露该、new Number(10)都是對象睬棚,他們都是引用類型。

??所有的對象都是由函數(shù)創(chuàng)建解幼。

1抑党、函數(shù)也是一個(gè)對象,由Function函數(shù)創(chuàng)建撵摆。

2底靠、var obj = { a: 10, b: 20}; var arr = [5, 'x',true]; 這類定義其實(shí)只是一個(gè)下面的語法糖而已

3、Function也是一個(gè)對象特铝,由它自己創(chuàng)建暑中,有趣吧

? 所有的函數(shù)都有prototype屬性(原型)

注意壹瘟,是函數(shù)才有prototype,普通對象沒有鳄逾。

函數(shù)創(chuàng)建時(shí)就自動(dòng)帶有這個(gè)屬性稻轨,也就是我們講的“原型”,這也絕對是js中最基礎(chǔ)也是最難的部分雕凹。

這個(gè)prototype的屬性值是一個(gè)對象(屬性的集合殴俱,再次強(qiáng)調(diào)!)请琳,默認(rèn)的只有一個(gè)叫做constructor的屬性粱挡,指向這個(gè)函數(shù)本身。

prototype可以添加自定義屬性俄精,你可以試試Object.prototype询筏,可以看到很多自定義的屬性:

? 所有的對象都有__proto__。

1竖慧、所有的對象都有__proto__嫌套,指向創(chuàng)建它的函數(shù)的prototype,注意圾旨,你要這樣來理解這句話的意思踱讨,那就是同一個(gè)函數(shù)new出來的對象的__proto__都統(tǒng)一指向了這個(gè)函數(shù)的prototype,根據(jù)后面要講述的原型鏈規(guī)則砍的,也就是說通過這個(gè)函數(shù)new出來的所有對象都可以直接使用該函數(shù)原型上的任意屬性和方法痹筛!,因此廓鞠,對于jquery的這種形式就應(yīng)該能理解了

$是jQuery的簡寫別名帚稠,其實(shí)是一個(gè)函數(shù)。因此$div是jQuery函數(shù)創(chuàng)建的對象床佳,很顯然滋早,on方法就是在jQuery.prototype上定義的屬性(函數(shù)),因此所有jQuery函數(shù)創(chuàng)建的對象都已直接使用on方法

2砌们、所有的函數(shù)杆麸,比如 function fn(){},都是由Function函數(shù)創(chuàng)建浪感,因此fn的__proto__指向Function的prototype昔头。

3、比較有意思的是影兽,F(xiàn)unction也是函數(shù)揭斧,因此它也由Function創(chuàng)建的,也就是說它自己創(chuàng)建了自己赢笨!所有Function的__proto__指向的就是Function的prototype未蝌!

4、同理茧妒,Object函數(shù)也是由Function創(chuàng)建萧吠,因此Object的__proto__同樣指向Function的prototype!

5桐筏、prototype也是一個(gè)對象纸型,原始prototype只有一個(gè)叫做constructor的屬性,指向這個(gè)函數(shù)本身梅忌。因?yàn)閜rototype是一個(gè)對象狰腌,因此它也是由Object方法創(chuàng)建,因此它的__proto__將指向Object.prototype牧氮,如下所示:

6琼腔、但是Object.prototype卻是一個(gè)特例——它的__proto__指向的是null,切記切記踱葛!

想想也覺得應(yīng)該是這樣吧

因此丹莲,根據(jù)上面的幾條基本概念,從這段簡單的代碼我們可以畫出這樣一條關(guān)系鏈圖:



原型鏈


以上圖為例尸诽,我們來對原型鏈進(jìn)行描述甥材。

首先person是個(gè)函數(shù),我們在它的原型(prototype)上添加了一個(gè)getName的方法(函數(shù)屬性)

然后zs是person new出來的一個(gè)對象性含,因此zs的__proto__指向person的prototype洲赵。

person.prototype作為一個(gè)普通對象,是有Object函數(shù)創(chuàng)建的商蕴,因此它的__proto__指向Object.prototype

我們看到叠萍,zs對象本身沒有g(shù)etName方法,那它是怎么訪問到的究恤?

原來在當(dāng)前對象中沒有找到某個(gè)屬性時(shí)俭令,它會(huì)順著__proto__屬性依次向上查找,知道找到為止部宿!因此抄腔,

getName屬性在zs對象中沒有找到,就會(huì)繼續(xù)找zs.__proto__理张,也就是person.prototype赫蛇,很顯然,這里找到了雾叭,就不會(huì)再向上查找了

hasOwnProperty屬性顯然zs對象中沒有找到悟耘,就會(huì)繼續(xù)找zs.__proto__,也就是person.prototype织狐,很顯然暂幼,person.prototype中也找不到筏勒,于是繼續(xù)向上在person.prototype.__proto__中找。person.prototype是一個(gè)普通對象旺嬉,它是由Object方法創(chuàng)建的管行,因此person.prototype.__proto__就是Object.prototype,很顯然邪媳,Object.prototype里面已經(jīng)定義了hasOwnProperty方法(屬性)捐顷,因此在這里也找到了。

上面這種查找形式就成為原型鏈雨效。就像一根鏈條一樣迅涮,依次向上鏈接起來。這也是ES5及之前的所謂“繼承”實(shí)現(xiàn)徽龟。

原型鏈訪問順序

我們注意到叮姑,在getName方法中是直接使用this.name來獲取zs對象的name值得,這就是說js在訪問原型對象的方法時(shí)据悔,直接把當(dāng)前對象應(yīng)用到了這個(gè)方法的上下文中戏溺。也就是相當(dāng)于:person.prototype.getName.apply(zs)

總結(jié)


要想正確理解掌握原型和原型鏈的概念,必須把上面講的最核心和基本的幾個(gè)概念理解和記住屠尊,否則看再多的案例也只會(huì)云里霧里旷祸,暈暈乎乎的,越加無法理解讼昆,靠死記硬背肯定是不行的托享。并且只要熟練掌握和牢記上面說的這幾個(gè)概念,不管遇到任何變著花樣的原型考查浸赫,都一定能夠正確理解闰围。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市既峡,隨后出現(xiàn)的幾起案子羡榴,更是在濱河造成了極大的恐慌,老刑警劉巖运敢,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件校仑,死亡現(xiàn)場離奇詭異,居然都是意外死亡传惠,警方通過查閱死者的電腦和手機(jī)迄沫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卦方,“玉大人羊瘩,你說我怎么就攤上這事。” “怎么了尘吗?”我有些...
    開封第一講書人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵逝她,是天一觀的道長。 經(jīng)常有香客問我睬捶,道長汽绢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任侧戴,我火速辦了婚禮,結(jié)果婚禮上跌宛,老公的妹妹穿的比我還像新娘酗宋。我一直安慰自己,他們只是感情好疆拘,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開白布蜕猫。 她就那樣靜靜地躺著,像睡著了一般哎迄。 火紅的嫁衣襯著肌膚如雪回右。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,184評(píng)論 1 308
  • 那天漱挚,我揣著相機(jī)與錄音翔烁,去河邊找鬼。 笑死旨涝,一個(gè)胖子當(dāng)著我的面吹牛蹬屹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播白华,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼慨默,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弧腥?” 一聲冷哼從身側(cè)響起厦取,我...
    開封第一講書人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎管搪,沒想到半個(gè)月后虾攻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡更鲁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年台谢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岁经。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡朋沮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情樊拓,我是刑警寧澤纠亚,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站筋夏,受9級(jí)特大地震影響蒂胞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜条篷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一骗随、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赴叹,春花似錦鸿染、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绽媒,卻和暖如春蚕冬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背是辕。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來泰國打工囤热, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人获三。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓赢乓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親石窑。 傳聞我的和親對象是個(gè)殘疾皇子牌芋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359

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

  • 理解 javascript 的原型鏈及繼承 以上所有的運(yùn)行結(jié)果都是 true; 三種構(gòu)造對象的方法: 通過對象字面...
    你期待的花開閱讀 1,519評(píng)論 0 3
  • 原型鏈?zhǔn)且环N機(jī)制,指的是 JavaScript 每個(gè)對象都有一個(gè)內(nèi)置的 __proto__ 屬性指向創(chuàng)建它的構(gòu)造函...
    劼哥stone閱讀 4,423評(píng)論 15 80
  • 請移步:https://blog.cdswyda.com/post/20161121
    依韻宵音閱讀 366評(píng)論 0 17
  • 在JavaScript中松逊,原型鏈作為一個(gè)基礎(chǔ)躺屁,老生長談,今天我們就來深入的解讀一下原型鏈经宏。 本章主要講的是下面幾點(diǎn)...
    Devinnn閱讀 1,405評(píng)論 1 6
  • 在JS中犀暑,原型鏈?zhǔn)且粋€(gè)重要的概念,不管是繼承還是屬性值的查找中烁兰,都用到了原型鏈的基本知識(shí)耐亏,有些朋友經(jīng)常問我一些關(guān)于...
    彬_仔閱讀 1,594評(píng)論 2 20