從JavaScript學習設計模式-02單例模式

保證一個類僅有一個實例,而且提供一個訪問它的全局訪問點javascript

單例模式的思路是:一個類能返回一個對象的引用(而且永遠是同一個)和一個得到該實例的方法(靜態方法,一般使用 getInstance 名稱)。那麼當咱們調用這個方法時,若是類持有的引用不爲空就返回該引用,否者就建立該類的實例,而且將實例引用賦值給該類保持的那個引用再返回。同時將該類的構造函數定義爲私有方法,避免其餘函數使用該構造函數來實例化對象,只經過該類的靜態方法來獲得該類的惟一實例。css

應用場景

平常開發中,常常製做彈窗的時候咱們須要一個半透明的遮罩層,爲了減小沒必要要的dom操做,咱們正確的思路應該是,判斷有沒有生成過這個 model div 若是已經生成了就沒必要再次生成。html

實現步驟

步驟1 寫一個生成 model div的方法

<style> .modal { position: fixed; left: 0; top: 0; width: 100%; height: 100%; opacity: .5; background: #000; z-index: 99; } </style>
  
 <script> function createModal () { const div = document.createElement('div'); div.className = 'modal'; document.body.appendChild(div); } createModal() createModal() // 調用兩次 將會產生兩個模態框 </script>  

複製代碼

調用兩次 createModal 方法將會產生在body上追加兩個div 很顯然不是咱們須要的結果,咱們須要增長一個變量判斷是否已經調用過java

根據單例模式的定義來實現

  1. 保證一個類僅有一個實例 new createModal()
  2. 而且提供一個訪問它的全局訪問點 createModal.getInstance 方法訪問
function createModal () {
    const div = document.createElement('div');
    div.className = 'modal';
    document.body.appendChild(div);
  }

  createModal.getInstance = function () {
    if (this.instace) {
      return this.instace;
    } else {
      this.instace = new createModal(); 
      return this.instace;
    }
  };
  const a = createModal.getInstance()
  const b = createModal.getInstance() // 調用兩次 實例一次
  console.log(a === b)  // true
複製代碼

此段代碼就根據單例模式的定義來用js實現了一個單例模式,調用屢次也只會實例一個 createModal ,生成一個模態框閉包

惰性單例

因爲js的特性,可用閉包的形式保護一個私有變量,讓他來做爲判斷值,而且惰性函數表明:在須要的時候才建立對象實例,而非在頁面加載時就建立app

const createModal = (function(){
    let div;
    return function(){
      if(!div){
        div = document.createElement('div');
        div.className = 'modal';
        document.body.appendChild(div);
      }
    }
  })();
  createModal()
  createModal() // 調用兩次 div 生成一次

複製代碼

經過閉包,保護了 div 變量,在調用時候判斷框架

通用模式

經過上面代碼咱們發現若是須要新建另一個div,只能複製代碼,是否能想辦法把 return 裏生成div 的方法分離出來呢。dom

  1. 建立一個 getSingle 方法 result 爲判斷變量
  2. 建立一個 createModal 的方法爲具體執行代碼,而且返回一個bool值給 getSingle 中的 result 進行判斷
const getSingle = function (fn) {
    let result;
    return function () {
      return result || (result = fn.apply(this, arguments));
    }
  };
  const createModal = function () {
    const div = document.createElement('div');
    div.className = 'modal';
    document.body.appendChild(div);
    return div
  }
  const createSingleDiv = getSingle(createModal)
  const a = createSingleDiv()
  const b = createSingleDiv()
  console.log(a === b)  // true
複製代碼

這樣就建立了一個 建立惰性單例的通用模式了函數

總結

單例模式在實際開發中應用不少,特別是在框架設計,合理利用能夠提升性能。性能

相關文章
相關標籤/搜索