摘要:測(cè)試目錄在文件中引入文件以下所有文件都在中玩原型構(gòu)造器一說(shuō)到原型一定和對(duì)象直接相關(guān)。的概念應(yīng)該理解的差不多了,下面我們?cè)僭鞄讉€(gè)構(gòu)造器作為練習(xí)。將構(gòu)造器中的方法拷貝到實(shí)例化的對(duì)象當(dāng)中。
測(cè)試目錄:
在html文件中引入js文件
以下所有文件都在base.js中玩~
一說(shuō)到原型,一定和對(duì)象直接相關(guān)。
以前我們這樣聲明一個(gè)對(duì)象
當(dāng)對(duì)象是一個(gè)用戶(hù)時(shí)
當(dāng)我們又需要一個(gè)用戶(hù)時(shí)
可以看到兩個(gè)對(duì)象的結(jié)構(gòu)無(wú)區(qū)別。
那么問(wèn)題來(lái)了,如果我們需要?jiǎng)?chuàng)建100個(gè)用戶(hù)時(shí),也要這么做嗎?當(dāng)然不要
兩個(gè)原因:
懶
用戶(hù)的信息是動(dòng)態(tài)的,我們不能在代碼中把它們寫(xiě)死。
所以想到一種辦法簡(jiǎn)化我們的工作:創(chuàng)建一個(gè)function專(zhuān)門(mén)為我們生成user
可以看出,打印的結(jié)果與前面的沒(méi)有任何區(qū)別~
但是我們卻少寫(xiě)了很多代碼。
這個(gè)function的本質(zhì)就是生成對(duì)象。
在這個(gè)function中,先新建一個(gè)空對(duì)象,然后將它填滿(mǎn),最后返回這個(gè)對(duì)象。
這樣的函數(shù)我們稱(chēng)它為工廠函數(shù)(Factory Function),專(zhuān)門(mén)生產(chǎn)對(duì)象。
在原生JS中,有一種更加簡(jiǎn)便的生產(chǎn)對(duì)象的方式
這個(gè)function中的this就代表它即將生成的對(duì)象。
注意:一旦使用這種方式來(lái)定義一個(gè)工廠函數(shù)時(shí),就要用new關(guān)鍵詞來(lái)叫它。
打印結(jié)果依然與前面的沒(méi)區(qū)別~
這種寫(xiě)法相當(dāng)于原生JS幫我們省去了聲明對(duì)象和返回對(duì)象的步驟。
像這樣用new關(guān)鍵詞叫的function通常我們稱(chēng)它為構(gòu)造器/構(gòu)造函數(shù)(Constructor),構(gòu)造函數(shù)的第一個(gè)字母一般大寫(xiě)。
不大寫(xiě)也沒(méi)關(guān)系,大寫(xiě)不過(guò)是為了讓其他人知道這是一個(gè)構(gòu)造函數(shù)。
Constructor的概念應(yīng)該理解的差不多了,下面我們?cè)僭鞄讉€(gè)構(gòu)造器作為練習(xí)。
實(shí)例一:
實(shí)例二:
原型-prototype和__proto__生成一個(gè)對(duì)象的過(guò)程叫實(shí)例化(Instantistion)。不管在哪種語(yǔ)言里面都一樣。
我們?cè)俳o這個(gè)構(gòu)造器加一些功能,比如greet和eat。
實(shí)例化一個(gè)對(duì)象whh
運(yùn)行whh.greet();
當(dāng)我們還需要一個(gè)用戶(hù)
可見(jiàn)兩位用戶(hù)都可以greet。但是注意,它們兩都實(shí)例了this.greet這個(gè)能力。也就是說(shuō),whh這個(gè)對(duì)象中有g(shù)reet這個(gè)能力(方法),lsd這個(gè)對(duì)象中也有同樣的方法。這兩個(gè)方法是完全獨(dú)立的,我們來(lái)驗(yàn)證這一點(diǎn),在控制臺(tái)中測(cè)試:
如圖,說(shuō)明它每實(shí)例化一次都會(huì)給自己創(chuàng)造一份與其它對(duì)象同樣的方法。在本例中也就是greet和eat方法。這里可以理解為拷貝代碼。將構(gòu)造器中的方法拷貝到實(shí)例化的對(duì)象當(dāng)中。
這個(gè)時(shí)候我們想 有必要一次次拷貝嗎?能不能想一種辦法把它們放到一個(gè)地方?當(dāng)實(shí)例化的對(duì)象要用的時(shí)候用一個(gè)東西就可以了。這就引入了原型(prototype)。
創(chuàng)建一個(gè)function。
在控制臺(tái)輸入a.prototype
發(fā)現(xiàn)它是一個(gè)對(duì)象。
原生JS就有這樣一個(gè)機(jī)制,在我們創(chuàng)建一個(gè)function的時(shí)候,它就首先給我們prototype這樣一個(gè)對(duì)象,放到function下。
為什么要這么做呢?prototype有什么用呢?
prototype就是用于給它即將生成的對(duì)象繼承下去的屬性。也就是說(shuō)我們一眼看不出來(lái),但它實(shí)際擁有的能力。我們來(lái)舉個(gè)栗子
它沒(méi)有在自有的屬性中顯示name屬性,而在繼承的屬性中顯示。但當(dāng)我們使用的時(shí)候是相當(dāng)于自己的屬性在用的。而且不管我們new了幾個(gè)對(duì)象,它們中的__proto__都是一樣的(其實(shí)是指向同一對(duì)象的)。下圖可驗(yàn)證。
既然如此,我們?cè)谝韵吕又芯涂梢园裧reet方法放到prototype中了。
修改為
在控制臺(tái)中
也就是說(shuō),現(xiàn)在的function只會(huì)存在一個(gè)地方,它不再需要每次都拷到實(shí)例的對(duì)象中去。
用原型的方式來(lái)指定一個(gè)方法還有一個(gè)好處,可以動(dòng)態(tài)更新。
當(dāng)我們想知道一個(gè)對(duì)象來(lái)自于那個(gè)工廠函數(shù),可以在控制臺(tái)中輸入 對(duì)象.constructor
如圖
那么就意味著,如果我們想復(fù)制一個(gè)對(duì)象的結(jié)構(gòu),可以這樣做:
這就相當(dāng)于
以上就是有關(guān)prototype和__proto__的邏輯。
原生對(duì)象的原型學(xué)到這里也許我們會(huì)有個(gè)疑問(wèn),當(dāng)我們就這樣創(chuàng)建一個(gè)對(duì)象時(shí),它的原型是什么呢?或者說(shuō)它有沒(méi)有父親呢?是誰(shuí)創(chuàng)建的它呢?
我們來(lái)打印一下就知道了~
它的constructor是一個(gè)叫Object的函數(shù),也就是說(shuō),它是有父親的。
也就是說(shuō),以下兩種寫(xiě)法是等價(jià)的。
我們來(lái)測(cè)試一下以上說(shuō)法是否正確。
聲明兩個(gè)對(duì)象
然后再控制臺(tái)中測(cè)試
也就是說(shuō)上面兩種創(chuàng)建對(duì)象的方法是等價(jià)的~
還有一種情況,當(dāng)我們想創(chuàng)建一個(gè)不繼承任何東西的對(duì)象時(shí)該怎么做呢?
我們可以這樣:
這樣我們就創(chuàng)建了一個(gè)最干凈的對(duì)象~
在參數(shù)中設(shè)置原型,比如
看到這里,我們應(yīng)該不再恐懼對(duì)象這個(gè)東西了,它的繼承關(guān)系我們已經(jīng)搞的很清楚了。
下面我們做個(gè)練習(xí):
a是一個(gè)數(shù)組,我們打印它
可以清楚的看到,它的constructor是一個(gè)叫Array的function
也就相當(dāng)于
兩種寫(xiě)法是等價(jià)的。
我們繼續(xù)往下看
Array()也有繼承的屬性,它的constructor是Object()。
綜上,如果Object()是爺爺,那么Array()就是爸爸,而我們聲明的數(shù)組對(duì)象a就是兒子。
我們來(lái)試一下從爸爸那繼承來(lái)的方法:(拿push方法來(lái)舉例)
證明它從爸爸那繼承下來(lái)的方法確實(shí)能用。
我們?cè)賮?lái)試一下從爺爺那繼承來(lái)的方法:(拿toString方法來(lái)舉例)
總結(jié):在JS中只要我們不明確的用Object.create()來(lái)創(chuàng)建對(duì)象,其余都是繼承Object.prototype的。
如何實(shí)現(xiàn)多級(jí)繼承鏈有這樣一條繼承鏈
這樣的一條繼承鏈在代碼中如何體現(xiàn)? 我們可以應(yīng)用到之前說(shuō)過(guò)的構(gòu)造器。
創(chuàng)建三個(gè)構(gòu)造器,并且使用Person構(gòu)造器創(chuàng)建一個(gè)叫l(wèi)sd的人。
我們從最頂級(jí)開(kāi)始看
實(shí)例兩個(gè)對(duì)象并打印
前面我們提到過(guò),實(shí)例出來(lái)的對(duì)象會(huì)各自拷一份能力。所以打印結(jié)果是false。
事實(shí)上這些純邏輯(純能力)的東西是沒(méi)有必要拷貝的,那我們?yōu)槭裁床粚⑺鼈兎诺皆椭腥ツ?
刷新網(wǎng)頁(yè)
此時(shí)的eat都是指向prototype的。相當(dāng)于借了一個(gè)能力過(guò)來(lái),而非拷貝一個(gè)能力過(guò)來(lái)。
接下來(lái)我們看Mammal這個(gè)構(gòu)造器
那么此時(shí)實(shí)例化的對(duì)象m有沒(méi)有eat和sleep這種能力呢?
可見(jiàn)是沒(méi)有的。因?yàn)榇藭r(shí)三個(gè)構(gòu)造器是獨(dú)立的,我們還沒(méi)有指定它們之間的繼承關(guān)系。那么如果指定這條繼承鏈呢?
拿Mammal和Animal說(shuō),Mammal不僅要繼承Animal的prototype,而且還要有自己的東西。
我們可以用到前面提到的create方法。
這種寫(xiě)法就相當(dāng)于 {__proto__:Animal.prototype}
現(xiàn)在我們?cè)賮?lái)測(cè)試一下實(shí)例化的對(duì)象m
這樣我們就可以說(shuō)它繼承成功了。
不過(guò)現(xiàn)在還有一個(gè)問(wèn)題,我們?cè)诳刂婆_(tái)調(diào)用一下m對(duì)象的constructor。
打印結(jié)果是Animal而非Mammal。而事實(shí)上Mammal才是m對(duì)象的constructor。這是為啥呢?
仔細(xì)看對(duì)象m的打印結(jié)果,發(fā)現(xiàn)并沒(méi)有constructor。
這是因?yàn)槲覀冊(cè)谇懊姘阉膒rototype重寫(xiě)了,覆蓋掉了。
所以才會(huì)繼承了上一級(jí)的constructor。
補(bǔ)救方法是,我們?cè)倜鞔_指定一下就可以啦。
大功告成~
接下來(lái)我們看Person
到這里我們就完成了原型的三級(jí)繼承~~~~撒花!
現(xiàn)在還有一個(gè)問(wèn)題,不同的動(dòng)物毛色可能不一樣,體重可能也不一樣,等等等。也就是說(shuō),它們會(huì)共有一些屬性,不過(guò)值不一樣。
我們可以這樣做:
此時(shí)實(shí)例化的對(duì)象中就有了我們用this指定的兩個(gè)顯性屬性"color"和"weight"
但是當(dāng)我們實(shí)例一個(gè)Mammal的對(duì)象并傳入?yún)?shù),然后打印。
我們發(fā)現(xiàn),打印出來(lái)的是一個(gè)空對(duì)象。
我們希望的是,只要是動(dòng)物(不管是哺乳動(dòng)物還是人),都存在毛色,體重等等屬性。
這個(gè)功能如何實(shí)現(xiàn)呢?
我們可以這樣做:
我們希望Mammal中的this與Animal中的this綁定到一塊。然后正常傳入?yún)?shù)。
在Person中同理
我們來(lái)打印一個(gè)Mammal中實(shí)例化的對(duì)象m做測(cè)試,看看它是否繼承Animal中的兩個(gè)顯性屬性。
我們?cè)賮?lái)試一下Person
我們?cè)賜ew一個(gè)Person。
可見(jiàn),顯性屬性是拷貝的。它們之間互不影響。這就是顯性屬性的繼承方式。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107578.html
摘要:首先為了模擬類(lèi)創(chuàng)建對(duì)象的功能搞出了構(gòu)造函數(shù)。也就是名字膚色膚色這里是繼承里的自有屬性生命值這里繼承的共有屬性的方法攻擊力兵種美國(guó)大兵攻擊防御死亡膚色 JS面向?qū)ο笾?【繼承】 我們已經(jīng)準(zhǔn)備了很多前置知識(shí),包括 原型鏈,對(duì)象和對(duì)象之間的關(guān)系 this,對(duì)象和函數(shù)之間的關(guān)系 new, 用函數(shù)批量創(chuàng)建特定的對(duì)象的語(yǔ)法糖 JS面向?qū)ο蟮那笆澜裆?我們說(shuō),面向?qū)ο笫且环N寫(xiě)代碼的套路。因?yàn)槿?..
摘要:因?yàn)轫?xiàng)目有可能用到所以學(xué)習(xí)了一下,做此筆記,圖截自慕課網(wǎng),侵刪。下一個(gè)筆記將會(huì)描述在代碼里的實(shí)際應(yīng)用。因?yàn)轫?xiàng)目有可能用到, 所以學(xué)習(xí)了一下,做此筆記,圖截自慕課網(wǎng),侵刪。 一、基本圖形 1、矩形 x,y定義矩形的左上角坐標(biāo); width,height定義矩形的長(zhǎng)度和寬度; rx,ry定義矩形的圓角半徑長(zhǎng)度,這里注意,如果rx給值了ry沒(méi)給值,ry沿用rx...
摘要:通過(guò)同一個(gè)構(gòu)造函數(shù)實(shí)例化的多個(gè)實(shí)例對(duì)象具有同一個(gè)原型對(duì)象。所以當(dāng)給原型對(duì)象賦值一個(gè)新對(duì)象時(shí),切記將原型對(duì)象的指回原構(gòu)造函數(shù)以上就是本次分享的內(nèi)容,關(guān)于原型對(duì)象的其他知識(shí),下一篇基礎(chǔ)原型對(duì)象的那些事二會(huì)講到。 談起js的基礎(chǔ),繞不過(guò)去的坎就是:原型鏈、作用域鏈、this(em...好吧,還有閉包),今天總結(jié)一下關(guān)于原型對(duì)象的一些知識(shí),供自己和大家復(fù)習(xí)。 概念理解 什么是原型對(duì)象呢?有以下...
摘要:實(shí)時(shí)彈幕使用云巴,直播平臺(tái)可快速實(shí)現(xiàn)視頻直播中發(fā)送彈幕打賞點(diǎn)贊等實(shí)時(shí)互動(dòng)功能。云巴聊天室支持圖片上傳文件發(fā)送文檔評(píng)論系統(tǒng)正式上線(xiàn)新增搜索功能,我們會(huì)做得更好。 SDK 篇 Android SDK 更新 Release 1.6.3后臺(tái)進(jìn)程相互拉起的特殊版本 Release 1.6.4增加 so 文件 Release 1.8.0支持小米、華為推送,無(wú)需注冊(cè)第三方賬號(hào) Release 1....
閱讀 2236·2023-04-25 19:06
閱讀 1434·2021-11-17 09:33
閱讀 1830·2019-08-30 15:53
閱讀 2638·2019-08-30 14:20
閱讀 3593·2019-08-29 12:58
閱讀 3592·2019-08-26 13:27
閱讀 561·2019-08-26 12:23
閱讀 536·2019-08-26 12:22