一、定義
-
設(shè)計(jì)模式
設(shè)計(jì)模式就是一種更好的編寫代碼方案。
-
常見設(shè)計(jì)模式
工廠設(shè)計(jì)模式、抽象工廠設(shè)計(jì)模式、抽象工廠設(shè)計(jì)模式,抽象工廠設(shè)計(jì)模式,觀察者設(shè)計(jì)模式,抓雙裝飾器模式,代理設(shè)計(jì)模式,MVC,MVP,MVVM 架構(gòu)設(shè)計(jì)模式。
-
常規(guī)定義
簡明定義:一個(gè)類對外有且僅有一個(gè)實(shí)例,這種編碼方案就是單件設(shè)計(jì)模式。
完整定義(有所缺失):如果某個(gè)類對外始終只提供一個(gè)對象,并且在該類的內(nèi)部提供了一個(gè)外部訪問該對象的方法或該對象屬性,那么這種編寫代碼方案就是單件設(shè)計(jì)模式。
如果一個(gè)類的任何外部通過訪問類提供的某個(gè)方法或某個(gè)屬性始終只能獲取該類的一個(gè)對象,但如果該類提供了多個(gè)外部可以訪問的方法或?qū)傩裕敲赐獠烤湍茉L問到該該類的多個(gè)不同的對象
單從實(shí)際開發(fā)來看,絕大對數(shù)情況的應(yīng)用場景,我們對外都只提供一個(gè)唯一的可以訪問的方法或?qū)傩?,這樣就保證了實(shí)例為單個(gè),類的這種編寫代碼的方案就是單件設(shè)計(jì)模式。
二、選型
-
什么時(shí)候選擇單件設(shè)計(jì)模式
實(shí)際發(fā)開中,外部訪問某個(gè)類的對象時(shí),確保只能訪問該類唯一對象時(shí)才能保證邏輯的正確性時(shí)就應(yīng)該使用單件設(shè)計(jì)模式了。
-
實(shí)際場景
Vuex、Redux 中的全局狀態(tài)管理容器 store對象在整個(gè)項(xiàng)目被設(shè)計(jì)成唯一的對象,把store對象所在的類設(shè)計(jì)成單件設(shè)計(jì)模式將是最好的設(shè)計(jì)方案,當(dāng)然也有其他代替寫法。
一般前端項(xiàng)目需要進(jìn)行客戶端本地?cái)?shù)據(jù)存儲(chǔ)時(shí)都會(huì)考慮使用 localStorage, localStorage 只要在相同的協(xié)議、相同的主機(jī)名、相同的端口下,就能讀取/修改道一份 localStorage 數(shù)據(jù).
項(xiàng)目日志記錄,為一個(gè)項(xiàng)目邊寫一個(gè)日志文件類,用來保存日志和閱讀日志信息。
-
為什么不零散得寫
問題1: 代碼零散
問題2: 可讀性很差,不能顧名思義
問題3: 對后期維護(hù)產(chǎn)生影響
問題4: 方法的代碼可以直接放到類里
OOP 面向?qū)ο笏枷?/p>
[圖片上傳失敗...(image-269029-1656773555186)]
[圖片上傳失敗...(image-f1d2c-1656773555186)]
[圖片上傳失敗...(image-9d02e3-1656773555186)]
// 構(gòu)建單件設(shè)計(jì)模式
// 第一步:把構(gòu)造器設(shè)置為私有的,不允許外部來創(chuàng)建類的實(shí)例【對象】
// 第二步: 至少應(yīng)該提供一個(gè)外部訪問的方法或?qū)傩?,外部可以通過這個(gè)方法或?qū)傩詠淼玫揭粋€(gè)對象
// 所以應(yīng)該把這個(gè)方法設(shè)置為靜態(tài)方法
// 第三步:外部調(diào)用第二步提供的靜態(tài)方法來獲取一個(gè)對象
[圖片上傳失敗...(image-967115-1656773555186)]
設(shè)置成私有的構(gòu)造函數(shù),外部就不可以訪問啦,然后通過靜態(tài)方法進(jìn)行創(chuàng)建
[圖片上傳失敗...(image-9eb42c-1656773555186)]
[圖片上傳失敗...(image-fbc902-1656773555186)]
我們需要在調(diào)用這個(gè)函數(shù)的時(shí)候展示一個(gè)
靜態(tài)的方法不可以訪問實(shí)例屬性,所以在類里定義一個(gè)靜態(tài)屬性
[圖片上傳失敗...(image-4acfc-1656773555186)]
[圖片上傳失敗...(image-ff2434-1656773555186)]
靜態(tài)會(huì)一直存在。 靜態(tài)會(huì)限制外部訪問它,只有靜態(tài)方法才能訪問靜態(tài)屬性。
-
靜態(tài)屬性的 9 大規(guī)則 + 靜態(tài)方法
外部如何調(diào)用 ts靜態(tài)屬性?類名直接調(diào)用靜態(tài)成員,格式:類名.靜態(tài)屬性 類名.靜態(tài)方法
靜態(tài)方法如何調(diào)用其他靜態(tài)成員? 用 this
靜態(tài)方法是否可以訪問類中原型對象上的方法或?qū)ο髮傩阅?,反過來? 不能 它們是相互獨(dú)立的。
對象變量是否可以訪問靜態(tài)成員?不能
一個(gè)靜態(tài)方法改變了某個(gè)靜態(tài)屬性,其他靜態(tài)方法或類外部任何地方訪問這個(gè)屬性都會(huì)發(fā)生改變。
靜態(tài)屬性 和 對象屬性【實(shí)例屬性】是類中的兩大成員,對象原型方法
- 靜態(tài)成員保存在內(nèi)存你那里?合適分配的內(nèi)存空間?
任何一個(gè)TS類中的靜態(tài)成員存儲(chǔ)在內(nèi)存的靜態(tài)區(qū),運(yùn)行一個(gè) TS 類,TS首先會(huì)為靜態(tài)成員開辟內(nèi)存空間,靜態(tài)成員的內(nèi)存空間分配的時(shí)間要早于對象空間的分配,也就是任何一個(gè)對象創(chuàng)建之前 TS 就已經(jīng)為靜態(tài)成員分配好了空間。但一個(gè)靜態(tài)方法只會(huì)分配一個(gè)空間,只要當(dāng)服務(wù)器不重啟或控制程序還沒有結(jié)束之前,靜態(tài)方法就一直存在內(nèi)存空間,無論調(diào)用多少次,都是調(diào)用同一塊空間。
總結(jié):
無論你是否創(chuàng)建對象,創(chuàng)建多少個(gè)對象,是否調(diào)用改靜態(tài)方法或靜態(tài)屬性,ts都會(huì)為這個(gè)靜態(tài)方法或靜態(tài)屬性分配內(nèi)存空間。
一旦為靜態(tài)方法或靜態(tài)屬性分配好空間就會(huì)一直存在內(nèi)存中,直到服務(wù)器重啟或者控制臺(tái)程序執(zhí)行結(jié)束才被釋放。
任何一個(gè)TS類中的靜態(tài)成員存儲(chǔ)在內(nèi)存的靜態(tài)去
靜態(tài)方法的調(diào)用 和 對象無關(guān)。
[圖片上傳失敗...(image-afc113-1656773555186)]
[圖片上傳失敗...(image-47c098-1656773555186)]
[圖片上傳失敗...(image-7bdc7a-1656773555186)
三、應(yīng)用·
何時(shí)應(yīng)該定義靜態(tài)方法、靜態(tài)屬性呢?
[圖片上傳失敗...(image-455404-1656773555186)]
[圖片上傳失敗...(image-10c3bd-1656773555186)]
[圖片上傳失敗...(image-7a10c5-1656773555186)]
這個(gè)方法只是被類收集了起來
[圖片上傳失敗...(image-a68d71-1656773555186)]
[圖片上傳失敗...(image-72a3ed-1656773555186)]
[圖片上傳失敗...(image-25a040-1656773555186)]
餓漢單件設(shè)計(jì)模式
[圖片上傳失敗...(image-a47089-1656773555186)]
[圖片上傳失敗...(image-f1332b-1656773555186)]
四、原理
-
靜態(tài)方法或?qū)傩栽谠蛯ο罂臻g上的方法或?qū)傩杂惺裁磪^(qū)別?
原型對象空間上的方法和屬性是用來提供給該類的所有對象變量公用的方法或?qū)傩?,沒有對象和對象變量,原型上的屬性和方法就沒有了用武之地,而靜態(tài)方法或靜態(tài)屬性屬于類,可以通過類來直接訪問。
任何一個(gè)對象創(chuàng)建之前,TS 就已經(jīng)為靜態(tài)成員分配好了空間。但一個(gè)靜態(tài)方法或靜態(tài)屬性只會(huì)分配一個(gè)空間,而每一個(gè)對象都有自己的獨(dú)立空間。
-
靜態(tài)方法內(nèi)部是否可以接受一個(gè)對象變量來作為方法的參數(shù)
[圖片上傳失敗...(image-d31c54-1656773555186)]
#繼承
一、定義
- 對象的 prototype 和 constructor都會(huì)指向同一個(gè)對象空間。
二、應(yīng)用
-
原型鏈繼承
Son.prototype = new Parent('王六', 38);
// 從指向自己的原型鏈空間到指向某一個(gè)類的原型鏈空間。
[圖片上傳失敗...(image-ce3e58-1656773555186)]
繼承之后,子類變量對象可以訪問父類的實(shí)例屬性
[圖片上傳失敗...(image-4d8c32-1656773555186)]
原型鏈繼承的完整描述:子對象首先在自己的對象空間中查找要訪問的屬性和方法,如果找到,就輸出。如果沒找到就沿著子對象中的 proto屬性指向的原型空間中去查找有沒有這個(gè)屬性或方法。 如果找到,就輸出,如果沒有找到就繼續(xù)沿著原型對象空間中的 protp 查找上一級原型對象空間中的屬性或方法,直到找到Object.prototype 原型對象屬性指向的原型對象空間為止,如果再找不到,就輸出 null。
-
原型鏈繼承容易被遺忘的一步
[圖片上傳失敗...(image-844bd0-1656773555186)]
掛載 constructor屬性,會(huì)通過 son類的對象 或函數(shù)原型 prototype 指向原型對象空間。
選型