對JavaScript原型鏈的理解

原型是什么?

在Java中,對象會從類中繼承屬性,方法等,但JavaScript中并沒有類的概念,JavaScript中的對象從原型對象中繼承屬性,方法。(雖然在ES6中引入class關(guān)鍵字,但本質(zhì)上是一種‘語法糖’,并不是真正意義上的類概念)。

一個‘神奇’的現(xiàn)象

我們先定義一個構(gòu)造器(函數(shù)):

function People(a,b,c){
    this.height = a;
    this.weight = b;
    this.age = c;
}

對于構(gòu)造器,訪問屬性prototype可以獲得它的原型對象:

console.log(People.prototype);

在瀏覽器控制臺中會顯示:


這就是它的原型對象。
如果點開constructor,會發(fā)現(xiàn)里面有里面包含proto屬性(并不是上圖中的proto,而是constructor中的proto),再點開proto會出現(xiàn)‘套娃’的情況:

又出現(xiàn)了constructor,再點開constructor里面還有proto屬性,這么一直點下去是無窮無盡的……
其中的proto屬性,指向一個對象的構(gòu)造函數(shù)的原型。
其實歸根結(jié)底,原因就一個式子:
構(gòu)造器(函數(shù))的原型對象(prototype)的構(gòu)造器(constructor)就是函數(shù)本身
結(jié)合上面的構(gòu)造函數(shù)就是:People == People.prototype.constructor
(也就是說一直點開下拉菜單相當(dāng)于不停輪流訪問prototype和constructor屬性,所以是無窮無盡的)

原型對象

說回原型,原型是個很抽象的概念,因為我們并不能看到它。當(dāng)定義了一個構(gòu)造器的時候,就會產(chǎn)生一個原型對象。這個構(gòu)造器所構(gòu)造的對象,都會從原型對象中繼承到屬性,方法等,我們定義一個小明‘xiaoming’對象,并打印出來:

var xiaoming = new People(170,60,18);
console.log(xiaoming);

在控制臺可以看到:


檢查小明對象的proto屬性,也就是小明對象的構(gòu)造器的原型對象,我們會發(fā)現(xiàn)它實際上就是上面我們看過的People構(gòu)造器的原型對象(People.prototype)。

那么什么是原型鏈呢?

其實理解了原型,就很好理解原型鏈了,我們發(fā)現(xiàn)小明對象繼承自People構(gòu)造器的原型對象,而People構(gòu)造器的原型對象又是從哪繼承的呢?上圖中最后一行proto,也就是

__proto__:Object

它就是JavaScript中的object(對象)的構(gòu)造函數(shù),點開它會發(fā)現(xiàn)它不再擁有proto屬性了,也就是它的proto屬性是null,這就說明尋找構(gòu)造函數(shù)到頭了,這就是所謂的原型鏈的終點。
事實上,隨便定義一個對象:

var xiaohei = {
    height:180,
    weight:80,
    age:20
}

然后去控制臺打印出來:

console.log(xiaohei);

會顯示:


它并沒有一個構(gòu)造函數(shù),它的原型對象的構(gòu)造函數(shù)就是object構(gòu)造函數(shù),事實上在JavaScript中不管什么對象,只要順著它的proto屬性往上尋找,就必然會回到object構(gòu)造函數(shù),也就是說JavaScript中任何對象都是object的實例。這就是原型鏈。

這篇文章比我說的牛批多了,沒看明白的去看這個吧:(得,講了半天不如給個鏈接)
https://juejin.im/post/5d713de26fb9a06ad3474c15
文章里面可能有錯誤,如果有讀者看到希望能指出

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容