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