亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

學(xué)習(xí)JavaScript之原型鏈

Leo_chen / 2026人閱讀

原型鏈之前一直都不是很理解,這兩天把《你不知道的JavaScript》和《JavaScript高級程序設(shè)計(jì)》的原型鏈那章看完后有所理解,在這里先記下來,加深印象。

什么是原型對象

要講清楚什么是原型鏈需要從原型對象開始談,那么什么是原型對象呢?《JavaScript高級程序設(shè)計(jì)》中是這樣講的:

無論什么時(shí)候,只要?jiǎng)?chuàng)建了一個(gè)新函數(shù),就會根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個(gè)prototype屬性,這個(gè)屬性指向函數(shù)的原型對象。

簡單來說,原型對象也是對象,但是通過原型對象可以實(shí)現(xiàn)對象的屬性繼承。
這里用《JavaScript高級程序設(shè)計(jì)》這本書上的demo來解釋一下:

function Person () {
}

Person.prototype.name = "Nicholas"
Person.prototype.age = 29
Person.prototype.job = "Software Engineer"
Person.prototype.sayName = function () {
  console.log(this.name)
}

var person1 = new Person()

var person2 = new Person()

這里聲明了一個(gè)Person函數(shù),沒有定義任何屬性;但是在Person的原型對象里定義了name,age,job屬性和sayName方法。之后創(chuàng)建了兩個(gè)Person的實(shí)例對象,person1和person2。在這里構(gòu)造函數(shù),原型對象,實(shí)例對象三者的關(guān)系用一張圖片表示就是
(圖片來源谷歌,侵刪)

如圖所示,Person的prototype指針指向它的原型對象,實(shí)例對象的[[Prototype]]指針也指向它的原型對象。這里簡單說明一下什么是[[Prototype]]指針:

調(diào)用構(gòu)造函數(shù)創(chuàng)建一個(gè)新實(shí)例之后,該實(shí)例的內(nèi)部將包含一個(gè)指針(內(nèi)部屬性),指向構(gòu)造函數(shù)的原型對象,這就是[[Prototype]]指針。

現(xiàn)在,person1和person2的[[Prototype]]都指向了Person.prototype,這樣的話Person.prototype里的方法和屬性是被person1和person2共用的。

如何證明他們共用Person.prototype里面的屬性和方法?請執(zhí)行下面的語句:

person1.sayName() // "Nicholas"
person2.sayName() // "Nicholas"

有人說了,你這初始化的name屬性只有一個(gè),執(zhí)行的結(jié)果當(dāng)然都一樣啊。那么請?jiān)僭囋囅旅孢@句:

console.log(person1.sayName === person2.sayName) //true

結(jié)果很明顯,person1.sayName和person2.sayName指向的是同一個(gè)方法。到這里可能有人會疑惑:一開始的代碼中Person函數(shù)里并沒有定義任何屬性和方法,為什么person1和person2能執(zhí)行sayName方法?那么這就要來談?wù)剬ο髮傩哉{(diào)用的過程了。

以上面代碼為例,當(dāng)你執(zhí)行person1.name時(shí),解析器會開始查找person1中有沒有name屬性,如果找到了則返回屬性值;如果沒找到,則在person1的原型對象中繼續(xù)找,找到了則返回屬性值;如果還沒找到,就沿著原型鏈往上繼續(xù)找,如果最終還是沒找到就返回undefined。

到這里大家也明白了多個(gè)對象實(shí)例共享原型對象的屬性和方法的基本原理了,那么有人又會問了,如果我通過給實(shí)例對象屬性賦值能不能重寫原型對象里的屬性和方法呢?

答案是不行的,在實(shí)例對象中對原型對象中的同名屬性賦值會屏蔽原型對象中的屬性。簡單解釋就是,對person1中的name屬性賦值會直接在person1中添加name屬性。但是有兩種情況下,當(dāng)name屬性不存在于person1中而存在于原型對象中時(shí),直接給person1.name賦值會有不一樣事情發(fā)生:
1.當(dāng)原型對象中的name屬性標(biāo)記為只讀(writable: false)時(shí),對name屬性的賦值不會在person1添加name屬性,也不會修改原型對象中的name屬性,在嚴(yán)格模式下還會報(bào)錯(cuò)。
2.當(dāng)原型對象中的name屬性是一個(gè)setter,那么對person1中的name屬性執(zhí)行賦值語句就會調(diào)用setter,但name不會被添加到person1中。
這部分如果不懂什么是只讀和setter,大家可以去看一下Object.defineProperty。

什么是原型鏈

其實(shí)講到這里,原型對象是什么已經(jīng)基本清楚了。那么原型鏈就很簡單了,繼續(xù)上面的demo:

function Parent () {
  this.parentName = "noOne"
}

function Person () {
  this.name = "Nicholas"
}

Person.prototype = new Parent()

var person1 = new Person()

這個(gè)例子中,我們把Parent的實(shí)例對象賦給了Person的原型對象。Person.prototype中的[[Prototype]]此時(shí)指向了Parent.prototype。舉一反三,Parent.prototype也可以是另一個(gè)原型的實(shí)例對象,這樣不斷地層層遞進(jìn)便構(gòu)成了原型鏈。

原型鏈的主要作用便是實(shí)現(xiàn)繼承,這部分后續(xù)的文章我會繼續(xù)講。

本人經(jīng)驗(yàn)尚淺,目前對于前端仍在不斷摸索和學(xué)習(xí),文章如有錯(cuò)誤,歡迎各位指正。最后附上本人博客地址和原文鏈接,希望能向各位多多學(xué)習(xí)。

lbj的前端之路
原文鏈接:學(xué)習(xí)JavaScript之原型鏈

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/91722.html

相關(guān)文章

  • 深入學(xué)習(xí)js——原型原型

    摘要:我們用一張圖表示構(gòu)造函數(shù)和實(shí)例原型之間的關(guān)系好了構(gòu)造函數(shù)和實(shí)例原型之間的關(guān)系我們已經(jīng)梳理清楚了,那我們怎么表示實(shí)例與實(shí)例原型,也就是或者和之間的關(guān)系呢。 開篇: 在Brendan Eich大神為JavaScript設(shè)計(jì)面向?qū)ο笙到y(tǒng)的時(shí)候,借鑒了Self 和Smalltalk這兩門基于原型的語言,之所以選擇基于原型的面向?qū)ο笙到y(tǒng),并不是因?yàn)闀r(shí)間匆忙,它設(shè)計(jì)起來相對簡單,而是因?yàn)閺囊婚_始B...

    FingerLiu 評論0 收藏0
  • 深入學(xué)習(xí)js——原型原型

    摘要:我們用一張圖表示構(gòu)造函數(shù)和實(shí)例原型之間的關(guān)系好了構(gòu)造函數(shù)和實(shí)例原型之間的關(guān)系我們已經(jīng)梳理清楚了,那我們怎么表示實(shí)例與實(shí)例原型,也就是或者和之間的關(guān)系呢。 開篇: 在Brendan Eich大神為JavaScript設(shè)計(jì)面向?qū)ο笙到y(tǒng)的時(shí)候,借鑒了Self 和Smalltalk這兩門基于原型的語言,之所以選擇基于原型的面向?qū)ο笙到y(tǒng),并不是因?yàn)闀r(shí)間匆忙,它設(shè)計(jì)起來相對簡單,而是因?yàn)閺囊婚_始B...

    xialong 評論0 收藏0
  • JavaScript高級程序設(shè)計(jì)學(xué)習(xí)筆記繼承模式

    摘要:實(shí)現(xiàn)原型鏈的方式如下讓原型對象稱為另一個(gè)構(gòu)造函數(shù)的實(shí)例這個(gè)實(shí)例繼承了的屬性上述代碼繼承是通過來實(shí)現(xiàn),創(chuàng)建的實(shí)例,并將該實(shí)例賦給。無疑,集兩者之大成,這才是最常用的繼承模式。 原型鏈 JavaScript的繼承主要依靠原型鏈來實(shí)現(xiàn)的。我們知道,構(gòu)造函數(shù),原型,和實(shí)例之間的關(guān)系:每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對象,原型對象都包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例都包含一個(gè)原型對象的指針。 實(shí)現(xiàn)原型鏈...

    suxier 評論0 收藏0
  • JavaScript 原型與周邊

    摘要:除此之外,原型是共享的,如果我們有的寫法,改變這兩個(gè)對象任何一個(gè)的原型都會影響另外一個(gè),這在大多的情況下是不可取的。當(dāng)對象查找一個(gè)屬性的時(shí)候,他會沿著原型鏈一直往上追蹤,直到直到為之。在性能方面,原則上應(yīng)該盡量避免原型鏈太長。 簡介 如果之間學(xué)習(xí)過cpp 、java 之類的語言,都會知道他們是可以基于類 class 進(jìn)行繼承的, 在JavaScript 中,并沒有類繼承這個(gè)概念,要實(shí)...

    codecook 評論0 收藏0
  • JavaScript深入原型原型

    摘要:深入系列的第一篇,從原型與原型鏈開始講起,如果你想知道構(gòu)造函數(shù)的實(shí)例的原型,原型的原型,原型的原型的原型是什么,就來看看這篇文章吧。讓我們用一張圖表示構(gòu)造函數(shù)和實(shí)例原型之間的關(guān)系在這張圖中我們用表示實(shí)例原型。 JavaScript深入系列的第一篇,從原型與原型鏈開始講起,如果你想知道構(gòu)造函數(shù)的實(shí)例的原型,原型的原型,原型的原型的原型是什么,就來看看這篇文章吧。 構(gòu)造函數(shù)創(chuàng)建對象 我們先...

    Songlcy 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<