【Javascript】設計模式之單例模式

文章目錄

  • 1、實現單例模式
  • 2、透明的單例模式
  • 3、用代理實現單例模式
  • 4、JavaScript 中的單例模式
  • 5、惰性單例
  • 6、通用的惰性單例
  • 7、小結

定義: 保證一個類僅有一個實例,并提供一個訪問它的全局訪問點
單例模式是一種常用的模式,有一些對象我們往往只需要一個,比如線程池、全局緩存、瀏
覽器中的 window 對象等

1、實現單例模式

是用一個變量來標志當前是否已經為某個類創建過對象,如果是,則在下一次獲取該類的實例時,直接返回之前創建的對象。
代碼如下:

var Singleton = function (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); // true

或者利用閉包:

var Singleton = function (name) {this.name = name;this.instance = null;
};
Singleton.getInstance = (function (name) {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); // true

問題:
就是增加了這個類的“不透明性”,Singleton 類的使用者必須知道這是一個單例類

2、透明的單例模式

實現一個“透明”的單例類,用戶從這個類中創建對象的時候,可以像使用其他任何普通類一樣。

在下面的例子中,我們將使用 CreateDiv 單例類,它的作用是負責在頁面中創建唯一的 div 節點,代碼如下:

var CreateDiv = (function () {var instance = null;var CreateDiv = function (html) {if (instance) {return instance;}this.html = html;this.init();return (instance = this);};CreateDiv.prototype.init = function () {var div = document.createElement('div');div.innerHTML = this.html;document.body.appendChild(div);};return CreateDiv;
})();var a = new CreateDiv('a');
var b = new CreateDiv('b');console.log(a === b);

問題:
問題:假設我們某天需要利用這個類,在頁面中創建千千萬萬的 div,即要讓這個類從單例類變成一個普通的可產生多個實例的類,那我們必須得改寫 CreateDiv 構造函數,把控制創建唯一對象的那一段去掉,這種修改會給我們帶來不必要的煩惱

解決:
使用代理模式

3、用代理實現單例模式

在 CreateDiv 構造函數中,把負責管理單例的代碼移除出去,使它成為一個普通的創建 div 的類:

var CreateDiv = function (html) {this.html = html;this.init();
};
CreateDiv.prototype.init = function () {var div = document.createElement('div');div.innerHTML = this.html;document.body.appendChild(div);
};// 引入代理類 proxySingletonCreateDiv:
var ProxySingletonCreateDiv = (function () {var instance;return function (html) {if (!instance) {instance = new CreateDiv(html);}return instance;};
})();var a = new ProxySingletonCreateDiv('a');
var b = new ProxySingletonCreateDiv('b');console.log(a === b);

跟之前不同的是,現在我們把負責管理單例的邏輯移到了代理類 proxySingletonCreateDiv 中。這樣一來,CreateDiv 就變成了一個普通的類,它跟 proxySingletonCreateDiv 組合起來可以達到單例模式的效果

4、JavaScript 中的單例模式

在 JavaScript 開發中,我們經常會把全局變量當成單例來使用。
例如:

var a = {};

問題:
全局變量存在很多問題,它很容易造成命名空間污染

解決:
1、使用命名空間

var namespace1 = { a: function(){ alert (1); }, b: function(){ alert (2); } 
};

2、使用閉包封裝私有變量

var user = (function(){ var __name = 'sven', __age = 29; return { getUserInfo: function(){ return __name + '-' + __age; } } 
})();

5、惰性單例

惰性單例指的是在需要的時候才創建對象實例
例子:

var createLoginLayer = (function () {var div;return function () {if (!div) {div = document.createElement('div');div.innerHTML = '我是浮窗';document.body.appendChild(div);}return div;}
})()// 用戶點擊按鈕的時候才開始創建該浮窗
document.getElementById('loginBtn').onclick = function () {var loginLayer = createLoginLayer();
};

問題:違反單一職責原則,創建對象和管理單例的邏輯都放在 createLoginLayer對象內部,如果我們下次需要創建頁面中唯一的 iframe,或者 script 標簽,用來跨域請求數據,就
必須得如法炮制,把 createLoginLayer 函數幾乎照抄一遍
解決:第6點

6、通用的惰性單例

將單例的邏輯從原來的代碼中抽離出來,這些邏輯被封裝在 getSingle函數內部,創建對象的方法 fn 被當成參數動態傳入 getSingle 函數

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 = '我是浮窗';document.body.appendChild(div);return div;
}
var createSingleLoginLayer = getSingle(createLoginLayer);document.getElementById('loginBtn').onclick = function () {var loginLayer = createSingleLoginLayer();
};

也可以用在只執行一次的函數
比如:給一個div綁定事件

var bindEvent = getSingle(function () {console.log('給div綁定事件~');return true;
});bindEvent();
bindEvent();
bindEvent();

7、小結

單例模式是一種簡單但非常實用的模式,特別是惰性單例技術,在合適的時候才創建對象,并且只創建唯一的一個。更奇妙的是,創建對象和管理單例的職責被分布在兩個不同的方法中,這兩個方法組合起來才具有單例模式的威力。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716648.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716648.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716648.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JavaScript 學習總結(16)—— 實用小函數總結

1.匹配正整數 // 匹配正整數 let isPositiveNum = val => {return /^[1-9]d*$/.test(val); }; console.log(isPositiveNum(9)) //true console.log(isPositiveNum(2.2)) //false 2.匹配負整數 // 匹配負整數let isNegativeNum = val => {return /^-[1-9]d*$/.test(val…

R750 install AMD MI210GPU

一、 查看服務器GPU卡信息 可以首先在服務器上check 當前GPU的詳細信息是否匹配 二、安裝 Ubuntu22.04操作系統 服務器CHECK 安裝的AMD GPU 是否被系統識別 #lspci | grep AMD 查看GPU信息 可以看到已經識別成功 三、安裝AMD GPU驅動 https://rocm.docs.amd.com/projec…

linux 根目錄下結構

/ 虛擬目錄的根的目錄,通常不會在這里放置文件 /bin:存放頻繁使用的命令,二進制文件,存放了很多用戶級的GNU實用工具。 /boot:引導目錄,存放引導文件,包含啟動Linux所需的核心文件。 /dev:設…

智能駕駛規劃控制理論學習05-車輛運動學規劃案例分析

目錄 案例一——Hybrid A*(基于正向運動學) 1、基本思想 2、 實現流程 3、啟發函數設計 4、分析擴張(Analytic Expansions) 5、分級規劃(Hierarchical planning) 案例二——State Lattice Planning&…

子矩陣的和 刷題筆記 {二維前綴和}

首先我們的目標是讓 s[i][j]表示為其左方和上方形成的矩陣所有元素的和 加上s[i-1][j]和s[i][j-1]后 s[i-1][j-1]部分重復了所以減去 最后加上a[i][j]即可完成目標 s[i][j]s[i-1][j]s[i][j-1]-s[i-1][j-1]a[i][j]; 然后看題目要求 要求x1,y1,x2,y2圍成的小正方形內的元素和…

C/C++工程師面試題(數據庫篇)

索引的優缺點 索引是一種支持快速查找特定行的數據結構,如果沒有索引,就需要遍歷整個表進行查找。用于提高數據檢索的速度和效率。 好處: 提高檢索速度: 索引可以加快數據的檢索速度,因為它們允許數據庫系統直接定位到…

Revit-二開之立面視圖創建FilledRegion-(3)

在上一篇博客中介紹了FilledRegion的創建方法,這種方法通常只在平面視圖中適用,在三維視圖中也是無法創建的(目前研究的是這樣的,如果有其他方法,請賜教)。 本片文章介紹一個下在立面視圖中創建FilledRegion的方法,主要操作是在立面視圖中拾取一個點,然后以該點為原點,…

YOLOv5 項目:推理代碼和參數詳細介紹(detect)

1、前言 本章將介紹yolov5項目的推理函數,關于yolov5的下載和配置環境,參考上一篇文章: YOLOv5 項目:環境配置-CSDN博客 pycharm 中打開的推理模塊如紅框中所示 pycharm將conda新建的虛擬環境導入,參考 :…

快速模冪(c++題解)

題目描述 試求ab%n的值,其中a、b、n均為整數范圍內的數。 輸入格式 三個整數即a、b、n。 輸出格式 輸出結果。 樣例 樣例輸入 復制1 1 1樣例輸出 復制0 _____________________________________________________________________________ ok呀總算學到一個…

從 AI 的爆火聊聊用戶界面(UI)的演進

目錄 用戶界面的起源與發展 用戶界面的設計原則與趨勢 用戶界面未來的方向 小結 用戶界面(User Interface,簡稱 UI)是人與計算機系統交互的媒介,用戶可以通過用戶界面向計算機發送指令,同時計算機可以通過用戶界面…

面試 Java 基礎八股文十問十答第十五期

面試 Java 基礎八股文十問十答第十五期 作者:程序員小白條,個人博客 相信看了本文后,對你的面試是有一定幫助的!關注專欄后就能收到持續更新! ?點贊?收藏?不迷路!? 1)BIO, NIO, AIO 有什么…

簡單實現Transformer的自注意力

簡單實現Transformer的自注意力 關注{曉理紫|小李子},獲取技術推送信息,如感興趣,請轉發給有需要的同學,謝謝支持!! 如果你感覺對你有所幫助,請關注我。 源碼獲取:VX關注并回復chatg…

二叉樹的右視圖,力扣

目錄 題目: 我們直接看題解吧: 快速理解解題思路小建議: 審題目事例提示: 解題方法: 解題分析: 解題思路: 代碼實現(DFS): 代碼1: 補充說明: 代碼2&#xff1…

Vue.js中的$nextTick

其實目前在我現有的開發經歷中,我還沒有實際運用過$nextTick,今天在看書時,學習到了這個東西,所以做個筆記記錄一下。 一、$nextTick是什么? $nextTick 是 Vue提供的一個方法,用于在 DOM 更新之后執行回調…

AI:148-開發一種智能語音助手,能夠理解和執行復雜任務

??點擊這里跳轉到本專欄,可查閱專欄頂置最新的指南寶典~ ?????? 你的技術旅程將在這里啟航! 從基礎到實踐,深入學習。無論你是初學者還是經驗豐富的老手,對于本專欄案例和項目實踐都有參考學習意義。 ??? 每一個案例都附帶關鍵代碼,詳細講解供大家學習,希望…

淺談鉤子方法

何為鉤子方法 鉤子方法(Hook methods)是一種在面向對象編程中常用的設計模式,也被稱為模板方法模式。在這種模式中,父類定義了一個算法的框架,并且將一些步驟的實現延遲到子類中。子類可以通過重寫這些“鉤子方法”來改…

[技巧]Arcgis之圖斑四至點批量計算

前言 上一篇介紹了arcgis之圖斑四至范圍計算,這里介紹的圖斑四至點的計算及獲取,兩者之間還是有差異的。 [技巧]Arcgis之圖斑四至范圍計算 這里說的四至點指的是圖斑最東、最西、最南、最北的四個地理位置點坐標,如下圖: 四至點…

青山隱隱,敗葉蕭蕭

給定序列需滿足二個條件:本身是質數,相鄰二項之和仍為質數 首先一個偶數2*n不能通過2*k(k取整數)得到質數。 奇數2*n-12*k2*(nk)-1,可能得到質數 那么若序列中存在偶數,一定不滿足第一個條件(特判0,2&am…

STM32進階筆記——復位、時鐘與滴答定時器

本專欄爭取每周三更新直到更新完成,期待大家的訂閱關注,歡迎互相學習交流。 目錄 一、復位1.1 軟件復位1.2 低功耗管理復位 二、時鐘2.1 系統時鐘(SYSCLK)選擇2.2 系統時鐘初始化 三、滴答定時器(Systick)3.1 SysTick部分寄存器3.…

部署bpmn項目實現activiti流程圖的在線繪制

本教程基于centos7.6環境中完成 github開源項目: https://github.com/Yiuman/bpmn-vue-activiti軟件:git、docker 1. 下載源代碼 git clone https://github.com/Yiuman/bpmn-vue-activiti.git2. 修改Dockerfile文件 聲明基礎鏡像,將項目打包&#xff…