原型鏈?zhǔn)乔岸嗣嬖嚴(yán)镆粋€經(jīng)久不衰的問題了,今天就像自己歸納一下這個問題:
首先萧求,我們先來看一張圖:
這個繞來繞去的線是不是很惡心呢其兴?那就先別管這些了,等整個邏輯我們梳理完就自然而然的會明白了~
一夸政、 什么是原型鏈元旬?
每個對象都可以有一個原型proto,這個原型還可以有它自己的原型守问,以此類推匀归,形成一個原型鏈。查找特定屬性的時候耗帕,我們先去這個對象里去找穆端,如果沒有的話就去它的原型對象里面去,如果還是沒有的話再去向原型對象的原型對象里去尋找...... 這個操作被委托在整個原型鏈上仿便,這個就是我們說的原型鏈了体啰。
二、原型指針
我們知道了原型的概念嗽仪,接下來我們就照著上面的圖來具體分析一下原型的指針荒勇;中間最上面藍(lán)色模塊標(biāo)注的構(gòu)造函數(shù)Foo, 里面有兩個屬性: proto 和 prototype, 這兩個很容易使人混淆,先說說prototype:
prototype:
prototype屬性闻坚,它是函數(shù)所獨有的沽翔,它是從一個函數(shù)指向一個對象。它的含義是函數(shù)的原型對象窿凤,也就是這個函數(shù)(其實所有函數(shù)都可以作為構(gòu)造函數(shù))所創(chuàng)建的實例的原型對象; 這個屬性是一個指針仅偎,指向一個對象,這個對象的用途就是包含所有實例共享的屬性和方法(我們把這個對象叫做原型對象);
proto:
proto 是原型鏈查詢中實際用到的雳殊,它總是指向 prototype橘沥,換句話說就是指向構(gòu)造函數(shù)的原型對象,它是對象獨有的相种。注意威恼,為什么Foo構(gòu)造也有這個屬性呢,因為再js的宇宙里萬物皆對象寝并,包括函數(shù)箫措;
根據(jù)以上的概括我們能知道Foo構(gòu)造函數(shù)proto指向的是他的構(gòu)造函數(shù)的原型對象,它的構(gòu)造函數(shù)是Function, 也就是說Foo的proto指向Function.prototype, 我們再看到左邊綠色的a和b函數(shù)的proto指像的是Foo.prototype,因為他們是通過 new Foo實例化出來的衬潦,它們的構(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:
我們看到途中最中間灰色模塊有一個constructor屬性弦牡,這個又是做什么用的呢?
每個函數(shù)都有一個原型對象漂羊,該原型對象有一個constructor屬性驾锰,指向創(chuàng)建對象的函數(shù)本身。
此外走越,我們還可以使用constructor屬性椭豫,所有的實例對象都可以訪問constructor屬性,constructor屬性是創(chuàng)建實例對象的函數(shù)的引用旨指。我們可以使用constructor屬性驗證實例的原型類型(與操作符instanceof非常類似)赏酥。
由于constructor屬性僅僅是原始構(gòu)造函數(shù)的引用,因此我們可以使用該屬性創(chuàng)建新的對象谆构,如:
通過第一個對象實例化對象的constuctor方法創(chuàng)建第2個實例化對象裸扶,說明創(chuàng)建的新對象ninja2 是Ninja的實例,由于ninja和ninja2不是同一個對象可以得出它們是兩個截然不同的實例搬素;
總結(jié)
1呵晨、proto 是原型鏈查詢中實際用到的,它總是指向 prototype熬尺;
2何荚、prototype 是函數(shù)所獨有的,在定義構(gòu)造函數(shù)時自動創(chuàng)建猪杭,它總是被 proto 所指餐塘。
所有對象都有proto屬性,函數(shù)這個特殊對象除了具有proto屬性皂吮,還有特有的原型屬性prototype戒傻。prototype對象默認(rèn)有兩個屬性,constructor屬性和proto屬性蜂筹。prototype屬性可以給函數(shù)和對象添加可共享(繼承)的方法需纳、屬性,而proto是查找某函數(shù)或?qū)ο蟮脑玩湻绞揭张病onstructor不翩,這個屬性包含了一個指針,指回原構(gòu)造函數(shù)。