国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js設計模式--單例模式

CloudwiseAPM / 1777人閱讀

摘要:文章系列設計模式單例模式設計模式策略模式設計模式代理模式概念單例模式的定義是保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。在開發中,單例模式的用途同樣非常廣泛。

前言

本系列文章主要根據《JavaScript設計模式與開發實踐》整理而來,其中會加入了一些自己的思考。希望對大家有所幫助。

文章系列

js設計模式--單例模式

js設計模式--策略模式

js設計模式--代理模式

概念

單例模式的定義是:保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。

UML類圖

場景

單例模式是一種常用的模式,有一些對象我們往往只需要一個,比如線程池、全局緩存、瀏 覽器中的 window 對象等。

在 JavaScript 開發中,單例模式的用途同樣非常廣泛。試想一下,當我們單擊登錄按鈕的時候,頁面中會出現一個登錄浮窗,而這個登錄浮窗是唯一的,無論單擊多少 次登錄按鈕,這個浮窗都只會被創建一次,那么這個登錄浮窗就適合用單例模式來創建。

優缺點

優點:創建對象和管理單例的職責被分布在兩個不同的方法中

實現 1. 我們的第一個單例
var instance = null
var getInstance = function(arg) {
  if (!instance) {
    instance = arg
  }
  return instance
}

var a = getInstance("a")
var b = getInstance("b")
console.log(a===b)

這種定義一個全局變量的方式非常不優雅,也不好復用代碼

2. 利用閉包實現單例
var Singleton = function( name ){
  this.name = name;
};

Singleton.getInstance = (function(){
  var instance = null;
  return function( name ){
    if ( !instance ){
      instance = new Singleton( name );
    }
    return instance;
  }
})();
var a = Singleton.getInstance("a")
var b = Singleton.getInstance("b")
console.log(a===b)

有些同學可能對閉包不大理解,下面用函數實現一下

3. 利用函數實現單例
function Singleton(name) {
  this.name = name
  this.instance = null
}

Singleton.getInstance = function(name) {
  if (!this.instance) {
    this.instance = new Singleton(name)
  }
  return this.instance
}

var a = Singleton.getInstance("a")
var b = Singleton.getInstance("b")
console.log(a===b)

2,3這兩種方式也有缺點,就是我們必須調用getInstance來創建對象,一般我們創建對象都是利用new操作符

4. 透明的單例模式
var Singleton = (function() {
  var instance
  Singleton = function(name) {
    if (instance) return instance
    this.name = name
    return instance = this
  }
  return Singleton
})()

var a = new Singleton("a")
var b = new Singleton("b")
console.log(a===b)

這中方法也有點缺點:不符合單一職責原則,這個對象其實負責了兩個功能:單例和創建對象

下面我們分離這兩個職責

5. 利用代理實現單例
var People = function(name) {
  this.name = name
}

var Singleton = (function() {
  var instance
  Singleton = function(name) {
    if (instance) return instance
    return instance = new People(name)
  }
  return Singleton
})()

var a = new Singleton("a")
var b = new Singleton("b")
console.log(a===b)

這中方法也有點缺點:代碼不能復用。如果我們有另外一個對象也要利用單例模式,那我們不得不寫重復的代碼

6. 提供通用的單例
var People = function(name) {
  this.name = name
}

var Singleton = function(Obj) {
  var instance
  Singleton = function() {
    if (instance) return instance
    return instance = new Obj(arguments)
  }
  return Singleton
}

var peopleSingleton = Singleton(People)

var a = new peopleSingleton("a")
var b = new peopleSingleton("b")
console.log(a===b)

到這里已經比較完美了,等等這只是es5的寫法,下面我們用es6來實現一下

7. es6單例模式
class People {
    constructor(name) {
        if (typeof People.instance === "object") {
            return People.instance;
        }
        People.instance = this;
        this.name = name
        return this;
    }
}
var a = new People("a")
var b = new People("b")
console.log(a===b)
比較以上幾種實現

用全局變量的第1種方法,應該摒棄

用閉包實現的第2種方式,instance 實例對象總是在我們調用 Singleton.getInstance 的時候才被創建,應該摒棄

其他方式都是惰性單例(在需要時才創建)

js的特殊性

我們都知道:JavaScript 其實是一門無類(class-free)語言,,生搬單例模式的概念并無意義。

單例模式的核心是確保只有一個實例,并提供全局訪問。

我們可以用一下幾種方式來另類實現

1. 全局變量

比如var a = {},這時全局就只有一個a對象
但全局變量存在很多問題,它很容易造成命名空間污染,我們用以下兩種方式解決

2.使用命名空間
  var namespace1 = {
    a: function () {
      alert(1);
    },
    b: function () {
      alert(2);
    }
  };

另外我們還可以動態創建命名空間

  var MyApp = {};
  MyApp.namespace = function (name) {
    var parts = name.split(".");
    var current = MyApp;
    for (var i in parts) {
      if (!current[parts[i]]) {
        current[parts[i]] = {};
      }
      current = current[parts[i]];
    }
  };
  MyApp.namespace("event");
  MyApp.namespace("dom.style");
  console.dir(MyApp);
  // 上述代碼等價于:
  var MyApp = {
    event: {},
    dom: {
      style: {}
    }
  };
3. 閉包
  var user = (function () {
    var __name = "sven",
      __age = 29;
    return {
      getUserInfo: function () {
        return __name + "-" + __age;
      }
    }
  })();
例子 登錄框

下面我們來實現一個點擊登錄按鈕彈出登錄框的例子

粗糙的實現



  




上面這種方式如果用戶沒有點擊登錄按鈕,也會在一開始就創建登錄框

改進



  



這種方式每次點擊按鈕都會創建一個登錄框

再改進
var createLoginLayer = (function () {
    var div;
    return function () {
      if (!div) {
        div = document.createElement("div");
        div.innerHTML = "我是登錄浮窗";
        div.style.display = "none";
        document.body.appendChild(div);
      }
      return div;
    }
  })();

  document.getElementById("loginBtn").onclick = function () {
    var loginLayer = createLoginLayer();
    loginLayer.style.display = "block";
  };

這種方式不夠通用,不符合單一職責原則

再再改進
  var getSingle = function (fn) {
    var result;
    return function () {
      return result || (result = fn.apply(this, arguments));
    }
  };

  var createLoginLayer = function () {
    var div = document.createElement("div");
    div.innerHTML = "我是登錄浮窗";
    div.style.display = "none";
    document.body.appendChild(div);
    return div;
  };
  var createSingleLoginLayer = getSingle(createLoginLayer);
  document.getElementById("loginBtn").onclick = function () {
    var loginLayer = createSingleLoginLayer();
    loginLayer.style.display = "block";
  };

  //下面我們再試試創建唯一的iframe 用于動態加載第三方頁面:
  var createSingleIframe = getSingle(function () {
    var iframe = document.createElement("iframe");
    document.body.appendChild(iframe);
    return iframe;
  });
  document.getElementById("loginBtn").onclick = function () {
    var loginLayer = createSingleIframe();
    loginLayer.src = "http://baidu.com";
  };

至此已經完美

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/100608.html

相關文章

  • JS 單例模式

    摘要:但是如何在對構造函數使用操作符創建多個對象的時候僅獲取一個單例對象呢。單例的實例引用單例構造函數單例私有屬性和方法暴露出來的對象改進之前在構造函數中重寫自身會丟失所有在初始定義和重定義之間添加到其中的屬性。 1. 單例模式 單例模式 (Singleton) 的實現在于保證一個特定類只有一個實例,第二次使用同一個類創建新對象的時候,應該得到與第一次創建對象完全相同的對象。當創建一個新對象...

    姘存按 評論0 收藏0
  • 淺談js單例模式

    摘要:單例模式說到單例設計模式,中經常使用的單例模式通常分兩種,懶漢模式和餓漢模式懶漢模式簡單寫了下私有化構造函數在獲取實例的方法中返回實例化對象雖然很多大佬都寫過啦,但是小生為了加深記憶便再寫一遍雖然實現了單例模式,但是未考慮到線程安全,多個線 java單例模式 說到單例設計模式,Java中經常使用java的單例模式通常分兩種,懶漢模式和餓漢模式 懶漢模式 class singleDemo...

    draveness 評論0 收藏0
  • js常用設計模式實現(一)單例模式

    摘要:什么是設計模式設計模式是一種能夠被反復使用,符合面向對象特性的代碼設計經驗的總結,合理的使用設計模式能夠讓你得代碼更容易維護和可靠設計模式的類型共分為創建型模式,結構型模式,行為型模式三種創建型模式創建型模式是對一個類的實例化過程進行了抽象 什么是設計模式 設計模式是一種能夠被反復使用,符合面向對象特性的代碼設計經驗的總結,合理的使用設計模式能夠讓你得代碼更容易維護和可靠設計模式的類型...

    EscapedDog 評論0 收藏0
  • 從ES6重新認識JavaScript設計模式(一): 單例模式

    摘要:什么是單例模式單例模式是一種十分常用但卻相對而言比較簡單的單例模式。對象就是單例模式的體現。總結單例模式雖然簡單,但是在項目中的應用場景卻是相當多的,單例模式的核心是確保只有一個實例,并提供全局訪問。 1. 什么是單例模式? 單例模式是一種十分常用但卻相對而言比較簡單的單例模式。它是指在一個類只能有一個實例,即使多次實例化該類,也只返回第一次實例化后的實例對象。單例模式不僅能減少不必要...

    G9YH 評論0 收藏0

發表評論

0條評論

CloudwiseAPM

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<