原型鏈?zhǔn)乔岸嗣嬖嚴(yán)镆粋€(gè)經(jīng)久不衰的問題了甩挫,自己也查閱了很多的資料滑黔,像紅寶書孵户、JavaScript忍者秘籍上都有對(duì)這一方面的描述和概括兽狭,今天就像自己歸納一下這個(gè)問題:
首先憾股,我們先來看一張圖:
這個(gè)繞來繞去的線是不是很惡心呢?那就先別管這些了箕慧,等整個(gè)邏輯我們梳理完就自然而然的會(huì)明白了~
一服球、 什么是原型鏈?
? ? ? ? 每個(gè)對(duì)象都可以有一個(gè)原型_proto_颠焦,這個(gè)原型還可以有它自己的原型斩熊,以此類推,形成一個(gè)原型鏈伐庭。查找特定屬性的時(shí)候粉渠,我們先去這個(gè)對(duì)象里去找,如果沒有的話就去它的原型對(duì)象里面去似忧,如果還是沒有的話再去向原型對(duì)象的原型對(duì)象里去尋找...... 這個(gè)操作被委托在整個(gè)原型鏈上渣叛,這個(gè)就是我們說的原型鏈了。
二盯捌、原型指針
? ? 我們知道了原型的概念淳衙,接下來我們就照著上面的圖來具體分析一下原型的指針;中間最上面藍(lán)色模塊標(biāo)注的構(gòu)造函數(shù)Foo, 里面有兩個(gè)屬性: _proto_ 和 prototype, 這兩個(gè)很容易使人混淆,先說說prototype:
prototype:
? ??prototype屬性箫攀,它是函數(shù)所獨(dú)有的肠牲,它是從一個(gè)函數(shù)指向一個(gè)對(duì)象。它的含義是函數(shù)的原型對(duì)象靴跛,也就是這個(gè)函數(shù)(其實(shí)所有函數(shù)都可以作為構(gòu)造函數(shù))所創(chuàng)建的實(shí)例的原型對(duì)象; 這個(gè)屬性是一個(gè)指針缀雳,指向一個(gè)對(duì)象,這個(gè)對(duì)象的用途就是包含所有實(shí)例共享的屬性和方法(我們把這個(gè)對(duì)象叫做原型對(duì)象);
__proto__:
? ??__proto__?是原型鏈查詢中實(shí)際用到的梢睛,它總是指向?prototype肥印,換句話說就是指向構(gòu)造函數(shù)的原型對(duì)象,它是對(duì)象獨(dú)有的绝葡。注意深碱,為什么Foo構(gòu)造也有這個(gè)屬性呢,因?yàn)樵賘s的宇宙里萬物皆對(duì)象藏畅,包括函數(shù)敷硅;
根據(jù)以上的概括我們能知道Foo構(gòu)造函數(shù)_proto_指向的是他的構(gòu)造函數(shù)的原型對(duì)象,它的構(gòu)造函數(shù)是Function, 也就是說Foo的_proto_指向Function.prototype,? 我們?cè)倏吹阶筮吘G色的a和b函數(shù)的_proto_指像的是Foo.prototype,因?yàn)樗麄兪峭ㄟ^ new Foo實(shí)例化出來的愉阎,它們的構(gòu)造函數(shù)就是Foo(), 即a._proto_ =?Foo.prototype绞蹦;? 接著我們來看看最右邊紫色的模塊Function.prororype, 它的_proto_指針指向的是Object.prototype,Object._proto_又為null.。于是我們就可以得出:在原型鏈中的指向是榜旦,函數(shù) → 構(gòu)造行數(shù)? → Function.prototype → Object.protype → null ;
constructor:
? ? 我們看到途中最中間灰色模塊有一個(gè)constructor屬性幽七,這個(gè)又是做什么用的呢?
每個(gè)函數(shù)都有一個(gè)原型對(duì)象溅呢,該原型對(duì)象有一個(gè)constructor屬性锉走,指向創(chuàng)建對(duì)象的函數(shù)本身。
? ? 此外藕届,我們還可以使用constructor屬性挪蹭,所有的實(shí)例對(duì)象都可以訪問constructor屬性,constructor屬性是創(chuàng)建實(shí)例對(duì)象的函數(shù)的引用休偶。我們可以使用constructor屬性驗(yàn)證實(shí)例的原型類型(與操作符instanceof非常類似)梁厉。
? ? 由于constructor屬性僅僅是原始構(gòu)造函數(shù)的引用,因此我們可以使用該屬性創(chuàng)建新的對(duì)象踏兜,如:
? ??
? ? 通過第一個(gè)對(duì)象實(shí)例化對(duì)象的constuctor方法創(chuàng)建第2個(gè)實(shí)例化對(duì)象词顾,說明創(chuàng)建的新對(duì)象ninja2 是Ninja的實(shí)例,由于ninja和ninja2不是同一個(gè)對(duì)象可以得出它們是兩個(gè)截然不同的實(shí)例碱妆;
結(jié)論:
? ? ? ? 1肉盹、__proto__?是原型鏈查詢中實(shí)際用到的,它總是指向?prototype疹尾;
? ? ? ? 2上忍、prototype 是函數(shù)所獨(dú)有的骤肛,在定義構(gòu)造函數(shù)時(shí)自動(dòng)創(chuàng)建,它總是被?__proto__?所指窍蓝。
所有對(duì)象都有__proto__屬性腋颠,函數(shù)這個(gè)特殊對(duì)象除了具有__proto__屬性,還有特有的原型屬性prototype吓笙。prototype對(duì)象默認(rèn)有兩個(gè)屬性淑玫,constructor屬性和__proto__屬性。prototype屬性可以給函數(shù)和對(duì)象添加可共享(繼承)的方法面睛、屬性絮蒿,而__proto__是查找某函數(shù)或?qū)ο蟮脑玩湻绞健onstructor叁鉴,這個(gè)屬性包含了一個(gè)指針歌径,指回原構(gòu)造函數(shù)。