成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

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

Leo_chen / 1951人閱讀

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

什么是原型對(duì)象

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

什么是原型鏈

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

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

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

Person.prototype = new Parent()

var person1 = new Person()

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

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

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/91722.html

相關(guān)文章

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

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

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

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

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

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

    suxier 評(píng)論0 收藏0
  • JavaScript 原型與周邊

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

    codecook 評(píng)論0 收藏0
  • JavaScript深入原型原型

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

    Songlcy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<