本篇內(nèi)容介紹了“JavaScript原型鏈的原理分析”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供自流井網(wǎng)站建設(shè)、自流井做網(wǎng)站、自流井網(wǎng)站設(shè)計(jì)、自流井網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、自流井企業(yè)網(wǎng)站模板建站服務(wù),十余年自流井做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
原型鏈?zhǔn)荍avaScript這門語言設(shè)計(jì)的十分有意思的地方之一。在解析原型鏈之前,我們需要了解以下幾個(gè)重要的概念。
構(gòu)造函數(shù)是一種比較特殊的函數(shù),它通常被人為地約定為函數(shù)名的首字母需要大寫,且必須通過new操作符來進(jìn)行調(diào)用(與普通函數(shù)的本質(zhì)上的區(qū)別),它的作用是用來創(chuàng)建特定類型的對象。在JavaScript中也一些原生的構(gòu)造函數(shù),如Object、Array、Function等等。
每當(dāng)構(gòu)造函數(shù)被new運(yùn)算符調(diào)用時(shí),都會(huì)創(chuàng)建出一個(gè)新對象,這個(gè)過程被稱為實(shí)例化。而這個(gè)對象就被稱為實(shí)例。也就是說任何對象都是一個(gè)實(shí)例,但關(guān)鍵在于創(chuàng)建這個(gè)實(shí)例的構(gòu)造函數(shù)是誰?以及它的原型是誰?
構(gòu)造函數(shù)內(nèi)部有個(gè)特殊的屬性prototype,這個(gè)屬性指向了一個(gè)對象,沒錯(cuò)它就是原型也稱為原型對象。原型對象是一個(gè)十分特殊存在,每當(dāng)構(gòu)造函數(shù)實(shí)例化一個(gè)對象時(shí),這個(gè)實(shí)例的[[Prototype]]會(huì)默認(rèn)指向構(gòu)造函數(shù)的prototype。實(shí)例對象可以通過自身的[[Porototyoe]]屬性找到原型對象,而原型對象可以通過自身的construcor屬性找到是哪個(gè)構(gòu)造函數(shù)創(chuàng)建了這個(gè)實(shí)例。(注意許多瀏覽器會(huì)把屬性[[Prototype]]替代為屬性__proto__。)
為了進(jìn)一步弄清楚構(gòu)造函數(shù)、實(shí)例和原型之間的關(guān)系,我們可以從下面這張圖片開始
實(shí)例dog通過自身的[[Prototype]]屬性找到了原型Dog.prototype
構(gòu)造函數(shù)Dog通過自身的prototype屬性找到了原型Dog.prototype
原型Dog.prototype則通過自身的constructor屬性找到了構(gòu)造函數(shù)Dog
實(shí)例dog通過constructor屬性找到了構(gòu)造函數(shù)Dog。
為實(shí)例dog通過constructor屬性找到了構(gòu)造函數(shù)Dog這個(gè)過程不用實(shí)線箭頭呢?這里到底有什么細(xì)節(jié)呢?,讓我們再來看一段簡單的代碼和一張圖片
function Dog(name){ this.name = name; } let dog = new Dog("cheems");
從代碼結(jié)合圖片來看,我們不難發(fā)現(xiàn)實(shí)例dog上并沒有constructor這個(gè)屬性,而原型對象才擁有這個(gè)屬性,那么實(shí)例是如何獲取到這個(gè)屬性呢? ,這就涉及到了JavaScript中一種特殊的行為——委托,下面我們就來了解一下什么是委托。
當(dāng)我們嘗試去獲取對象的某個(gè)屬性值,但該對象并沒有這個(gè)屬性時(shí),那么JavaScript 會(huì)試著從原型對象中獲取屬性值。如果那個(gè)原型對象也沒有該屬性,那么再從它的原型中尋找,依次類推直到該過程最后到達(dá)終點(diǎn)Object.prototype,如果仍然沒有找到就返回undefined。這個(gè)過程被稱為委托。
現(xiàn)在你就明白了,實(shí)例dog正是通過委托這種方式找到了創(chuàng)建自己的構(gòu)造函數(shù)。在明白這一點(diǎn)之后,原型鏈也就呼之欲出了。
如果在第一個(gè)對象上沒有找到需要的屬性或者方法引用,引擎就會(huì)繼續(xù)在它的[[Prototype]]指向的對象上進(jìn)行查找。同理如果后者中也沒有找到需要的引用就會(huì)繼續(xù)查找它的[[Prototype]],依次類推直到到達(dá)Object.prototype,這一系列對象的鏈接被稱為原型鏈。
我們可以用一張圖來表示下
由于構(gòu)造函數(shù)也是對象,所以它同樣具有構(gòu)造函數(shù)和原型。構(gòu)造函數(shù)的prototype是實(shí)例的原型,并非自身的原型。自定義的構(gòu)造函數(shù)同樣需要借助[[Prototype]]找到原型,進(jìn)而找到創(chuàng)建自己的構(gòu)造函數(shù)——即原生構(gòu)造函數(shù)Function,但請注意原生的構(gòu)造函數(shù)Function的[[Prototype]]是指向了Function.prototype。
console.log(Function.__proto__ === Function.prototype); // true
所有的原型對象都可以沿著原型鏈一直尋找至到找到最后的原型對象Object.prototype,然后Object.prototype再往上尋找就是Null,用來表示此處沒有對象。
“JavaScript原型鏈的原理分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!