<menu id="ycqsw"></menu><nav id="ycqsw"><code id="ycqsw"></code></nav>
<dd id="ycqsw"><menu id="ycqsw"></menu></dd>
  • <nav id="ycqsw"></nav>
    <menu id="ycqsw"><strong id="ycqsw"></strong></menu>
    <xmp id="ycqsw"><nav id="ycqsw"></nav>
  • js移除div里面內容(引入外部css文件的方式)


    定義

    確保一個類僅有一個實例,并提供一個訪問它的全局訪問點。

    特點:

    1. 可以來劃分命名空間,從而清除全局變量所帶來的風險。
    2. 可以把代碼組織的更為一體,便于閱讀和維護。
    3. 可以被實例化,且實例化一次。

    單例模式使用的場景

    比如線程池、全局緩存等。我們所熟知的瀏覽器的window對象就是一個單例,在JavaScript開發中,對于這種只需要一個的對象,我們的實現往往使用單例。

    實現單例模式 (不透明的)

    一般我們是這樣實現單例的,用一個變量來標志當前的類已經創建過對象,如果下次獲取當前類的實例時,直接返回之前創建的對象即可。代碼如下:

    JavaScript設計模式之單例模式(Singleton Pattern)

    我們也可以使用閉包來實現:

    JavaScript設計模式之單例模式(Singleton Pattern)

    這個單例實現獲取對象的方式經常見于新手的寫法,這種方式獲取對象雖然簡單,但是這種實現方式不透明。知道的人可以通過 Singleton.getInstance() 獲取對象,不知道的需要研究代碼的實現,這樣不好。這與我們常見的用 new 關鍵字來獲取對象有出入,實際意義不大。

    實現單例模式 (透明的)

    JavaScript設計模式之單例模式(Singleton Pattern)

    這種單例模式我以前用過一次,但是使用起來很別扭,我也見過別人用這種方式實現過走馬燈的效果,因為走馬燈在我們的應用中絕大多數只有一個。

    這里先說一下為什么感覺不對勁,因為在這個單例的構造函數中一共干了兩件事,一個是創建對象并打印實例名字,另一個是保證只有一個實例對象。這樣代碼量大的化不方便管理,應該盡量做到職責單一。

    我們通常會將代碼改成下面這個樣子:

    JavaScript設計模式之單例模式(Singleton Pattern)

    這種實現方式我們就比較熟悉了,我們在開發中經常會使用中間類,通過它來實現原類所不具有的特殊功能。有的人把這種實現方式叫做代理,這的確是單例模式的一種應用,稍后將在代理模式進行詳解。

    說了這么多我們還是在圍繞著傳統的單例模式實現在進行講解,那么具有JavaScript特色的單例模式是什么呢。

    JavaScript單例模式

    在我們的開發中,很多同學可能并不知道單例到底是什么,應該如何使用單例,但是他們所寫的代碼卻剛好滿足了單例模式的要求。如要實現一個登陸彈窗,不管那個頁面或者在頁面的那個地方單擊登陸按鈕,都會彈出登錄窗。一些同學就會寫一個全局的對象來實現登陸窗口功能,是的,這樣的確可以實現所要求的登陸效果,也符合單例模式的要求,但是這種實現其實是一個巧合,或者一個美麗的錯誤。由于全局對象,或者說全局變量正好符合單例的能夠全局訪問,而且是唯一的。但是我們都知道,全局變量是可以被覆蓋的,特別是對于初級開發人員來說,剛開始不管定義什么基本都是全局的,這樣的好處是方便訪問,壞處是一不留意就會引起沖突,特別是在做一個團隊合作的大項目時,所以成熟的有經驗的開發人員盡量減少全局的聲明。

    而在開發中我們避免全局變量污染的通常做法如下:

    • 全局命名空間
    • 使用閉包

    它們的共同點是都可以定義自己的成員、存儲數據。區別是全局命名空間的所有方法和屬性都是公共的,而閉包可以實現方法和屬性的私有化。

    惰性單例模式

    說實話,在我下決心學習設計模式之前我并不知道,單例模式還分惰性單例模式,直到我看了曾探大神的《JvaScript設計模式與開發實踐》后才知道了還有惰性單例模式,那么什么是惰性單例模式呢?在說惰性單例模式之前,請允許我先說一個我們都知道的lazyload加載圖片,它就是惰性加載,只當含有圖片資源的dom元素出現在媒體設備的可視區時,圖片資源才會被加載,這種加載模式就是惰性加載;還有就是下拉刷新資源也是惰性加載,當你觸發下拉刷新事件資源才會被加載等。而惰性單例模式的原理也是這樣的,只有當觸發創建實例對象時,實例對象才會被創建。這樣的實例對象創建方式在開發中很有必要的。

    就如同我們剛開始介紹的用 Singleton.getInstance 創建實例對象一樣,雖然這種方式實現了惰性單例,但是正如我們剛開始說的那樣這并不是一個好的實現方式。下面就來介紹一個好的實現方式。

    遮罩層相信大家對它都不陌生。它在開發中比較常見,實現起來也比較簡單。在每個人的開發中實現的方式不盡相同。這個最好的實現方式還是用單例模式。有的人實現直接在頁面中加入一個div然后設置display為none,這樣不管我們是否使用遮罩層頁面都會加載這個div,如果是多個頁面就是多個div的開銷;也有的人使用js創建一個div,當需要時就用將其加入到body中,如果不需要就刪除,這樣頻繁地操作dom對頁面的性能也是一種消耗;還有的人是在前一種的基礎上用一個標識符來判斷,當遮罩層是第一次出現就向頁面添加,不需要時隱藏,如果不是就是用前一次的添加的。

    JavaScript設計模式之單例模式(Singleton Pattern)

    我們發現在開發中并不會單獨使用遮罩層,遮罩層和彈出窗是經常結合在一起使用,前面我們提到過登陸彈窗使用單例模式實現也是最適合的。那么我們是不是要將上面的代碼拷貝一份呢?當然我們還有好的實現方式,那就是將上面單例中代碼變化的部分和不變的部分,分離開來。

    JavaScript設計模式之單例模式(Singleton Pattern)

    在上面的實現中將單例模式的惰性實現部分提取出來,實現了惰性實現代碼的復用,其中使用apply改變改變了fn內的this指向,使用 || 預算簡化代碼的書寫。

    ES6中的單例模式

    ES6創建對象

    ES6中創建對象時引入了class和constructor用來創建對象。下面我們來使用ES6的語法實例化蘋果公司

    JavaScript設計模式之單例模式(Singleton Pattern)

    ES6中創建單例模式

    蘋果這么偉大的公司明顯有且只有一個, 就是喬爺爺創建的那個, 哪能容別人進行復制?所以appleCompany應該是一個單例, 現在我們使用ES6的語法將constructor改寫為單例模式的構造器。

    JavaScript設計模式之單例模式(Singleton Pattern)

    ES6的靜態方法優化代碼

    ES6中提供了為class提供了static關鍵字定義靜態方法, 我們可以將constructor中判斷是否實例化的邏輯放入一個靜態方法getInstance中,調用該靜態方法獲取實例, constructor中只包需含實例化所需的代碼,這樣能增強代碼的可讀性、結構更加優化。

    JavaScript設計模式之單例模式(Singleton Pattern)

    實現登陸彈框

    登陸彈框在項目中是一個比較經典的單例模式,因為對于大部分網站不需要用戶必須登陸才能瀏覽,所以登陸操作的彈框可以在用戶點擊登陸按鈕后再進行創建。而且登陸框永遠只有一個,不會出現多個登陸彈框的情況,也就意味著再次點擊登陸按鈕后返回的永遠是一個登錄框的實例。

    現在來梳理一下我登陸彈框的流程,在來進行代碼的實現:

    1. 給頂部導航模塊的登陸按鈕注冊點擊事件
    2. 登陸按鈕點擊后JS動態創建
    3. 遮罩層和登陸彈框遮罩層和登陸彈框插入到頁面中
    4. 給登陸框中的關閉按鈕注冊事件, 用于關閉遮罩層和彈框
    JavaScript設計模式之單例模式(Singleton Pattern)

    上面的登陸框的實現中,我們只創建了一個Login的類, 但是卻實現了一個并不簡單的登陸功能。在第一次點擊登陸按鈕的時候,我們調用Login.getInstance()實例化了一個登陸框,且在之后的點擊中,并沒有重新創建新的登陸框,只是移除掉了”display: none”這個樣式來顯示登陸框,節省了內存開銷。


    總結

    單例模式雖然簡單,但是在項目中的應用場景卻是相當多的。單例模式的核心是確保只有一個實例, 并提供全局訪問。就像我們只需要一個瀏覽器的window對象, jQuery的$對象而不再需要第二個。 由于JavaScript代碼書寫方式十分靈活, 這也導致了如果沒有嚴格的規范的情況下,大型的項目中JavaScript不利于多人協同開發, 使用單例模式進行命名空間,管理模塊是一個很好的開發習慣,能夠有效的解決協同開發變量沖突的問題。靈活使用單例模式,也能夠減少不必要的內存開銷,提高用于體驗。

    版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。

    發表評論

    登錄后才能評論
    国产精品区一区二区免费