說說你對單例模式的理解?如何實現?

来源:https://www.cnblogs.com/smileZAZ/p/18225134
-Advertisement-
Play Games

一、是什麼 單例模式(Singleton Pattern):創建型模式,提供了一種創建對象的最佳方式,這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建 在應用程式運行期間,單例模式只會在全局作用域下創建一次實例對象,讓所有需要調用的地方都共用這一單例對象,如下圖所示: ...


 

一、是什麼

單例模式(Singleton Pattern):創建型模式,提供了一種創建對象的最佳方式,這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建

在應用程式運行期間,單例模式只會在全局作用域下創建一次實例對象,讓所有需要調用的地方都共用這一單例對象,如下圖所示:

 

從定義上來看,全局變數好像就是單例模式,但是一般情況我們不認為全局變數是一個單例模式,原因是:

  • 全局命名污染
  • 不易維護,容易被重寫覆蓋

二、實現

javascript中,實現一個單例模式可以用一個變數來標誌當前的類已經創建過對象,如果下次獲取當前類的實例時,直接返回之前創建的對象即可,如下:

// 定義一個類
function Singleton(name) {
    this.name = name;
    this.instance = null;
}
// 原型擴展類的一個方法getName()
Singleton.prototype.getName = function() {
    console.log(this.name)
};
// 獲取類的實例
Singleton.getInstance = function(name) {
    if(!this.instance) {
        this.instance = new Singleton(name);
    }
    return this.instance
};

// 獲取對象1
const a = Singleton.getInstance('a');
// 獲取對象2
const b = Singleton.getInstance('b');
// 進行比較
console.log(a === b);

使用閉包也能夠實現,如下:

function Singleton(name) {
    this.name = name;
}
// 原型擴展類的一個方法getName()
Singleton.prototype.getName = function() {
    console.log(this.name)
};
// 獲取類的實例
Singleton.getInstance = (function() {
    var instance = null;
    return function(name) {
        if(!this.instance) {
            this.instance = new Singleton(name);
        }
        return this.instance
    }        
})();

// 獲取對象1
const a = Singleton.getInstance('a');
// 獲取對象2
const b = Singleton.getInstance('b');
// 進行比較
console.log(a === b);

也可以將上述的方法稍作修改,變成構造函數的形式,如下:

// 單例構造函數
function CreateSingleton (name) {
    this.name = name;
    this.getName();
};

// 獲取實例的名字
CreateSingleton.prototype.getName = function() {
    console.log(this.name)
};
// 單例對象
const Singleton = (function(){
    var instance;
    return function (name) {
        if(!instance) {
            instance = new CreateSingleton(name);
        }
        return instance;
    }
})();

// 創建實例對象1
const a = new Singleton('a');
// 創建實例對象2
const b = new Singleton('b');

console.log(a===b); // true

三、使用場景

在前端中,很多情況都是用到單例模式,例如頁面存在一個模態框的時候,只有用戶點擊的時候才會創建,而不是載入完成之後再創建彈窗和隱藏,並且保證彈窗全局只有一個

可以先創建一個通常的獲取對象的方法,如下:

const getSingle = function( fn ){
  let result;
  return function(){
    return result || ( result = fn .apply(this, arguments ) );
  }
}; 

創建彈窗的代碼如下:

const createLoginLayer = function(){
  var div = document.createElement( 'div' );
  div.innerHTML = '我是浮窗';
  div.style.display = 'none';
  document.body.appendChild( div );
  return div;
}; 

const createSingleLoginLayer = getSingle( createLoginLayer ); 

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

上述這種實現稱為惰性單例,意圖解決需要時才創建類實例對象

並且Vuexredux全局態管理庫也應用單例模式的思想,如下圖:

 

現在很多第三方庫都是單例模式,多次引用只會使用同一個對象,如jquerylodashmoment...

參考文獻

  • https://zh.wikipedia.org/zh-hans/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F
  • https://www.runoob.com/design-pattern/singleton-pattern.html
  • https://juejin.cn/post/6844903874210299912#heading-5

 

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • FormCreate 是一個可以通過 JSON 生成具有動態渲染、數據收集、驗證和提交功能的表單生成組件。支持5個UI框架,並且支持生成任何 Vue 組件。內置20種常用表單組件和自定義組件,再複雜的表單都可以輕鬆搞定 FormCreate官網:https://www.form-create.com ...
  • 初探富文本之基於虛擬滾動的大型文檔性能優化方案 虛擬滾動是一種優化長列表性能的技術,其通過按需渲染列表項來提高瀏覽器運行效率。具體來說,虛擬滾動只渲染用戶瀏覽器視口部分的文檔數據,而不是整個文檔結構,其核心實現根據可見區域高度和容器的滾動位置計算出需要渲染的列表項,同時不渲染額外的視圖內容。虛擬滾動 ...
  • title: Vue.js 動態組件與非同步組件 date: 2024/6/2 下午9:08:50 updated: 2024/6/2 下午9:08:50 categories: 前端開發 tags: Vue概覽 動態組件 非同步載入 性能提升 路由管理 狀態控制 工具生態 第1章 Vue.js 簡介 ...
  • 從零學習Vue.js 目錄 引言 準備工作 Vue.js 基礎 3.1 Vue 實例 3.2 模板語法 3.3 數據綁定 3.4 計算屬性和偵聽器 3.5 Class 與 Style 綁定 3.6 條件渲染 3.7 列表渲染 3.8 事件處理 3.9 表單輸入綁定 Vue.js 組件 4.1 組件基 ...
  • title: Vue插槽與作用域插槽 date: 2024/6/1 下午9:07:52 updated: 2024/6/1 下午9:07:52 categories: 前端開發 tags: VueSlot ScopeSlot 組件通信 Vue2/3插槽 作用域API 動態插槽 插槽優化 第1章:插槽 ...
  • 一、背景 在日常佈局中,無論是兩欄佈局還是三欄佈局,使用的頻率都非常高 兩欄佈局 兩欄佈局實現效果就是將頁面分割成左右寬度不等的兩列,寬度較小的列設置為固定寬度,剩餘寬度由另一列撐滿, 比如 Ant Design 文檔,藍色區域為主要內容佈局容器,側邊欄為次要內容佈局容器 這裡稱寬度較小的列父元素為 ...
  • XML Web服務是基於WSDL、SOAP、RDF和RSS等標準的網路應用程式組件技術。WSDL描述服務介面和消息格式,SOAP用於結構化信息交換,RDF描述網路資源,RSS則用於發佈網站更新。Web服務特點是自包含、自描述,基於開放協議,可重用且能連接現有軟體。WSDL文檔包含`types`、`m... ...
  • title: vue3組件通信與props date: 2024/5/31 下午9:00:57 updated: 2024/5/31 下午9:00:57 categories: 前端開發 tags: Vue3組件 Props詳解 生命周期 數據通信 模板語法 Composition API 單向數據 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...