利用ES6實現(xiàn)單例模式及其應(yīng)用詳解
前言
在傳統(tǒng)開發(fā)工程師眼里,單例就是保證一個類只有一個實例,實現(xiàn)的方法一般是先判斷實例存在與否,如果存在直接返回,如果不存在就創(chuàng)建了再返回,這就確保了一個類只有一個實例對象。在JavaScript里,單例作為一個命名空間提供者,從全局命名空間里提供一個唯一的訪問點來訪問該對象。
單例模式的定義是:保證一個類僅有一個一個實例,并提供一個訪問它的全局訪問點。
單例模式能在合適的時候創(chuàng)建對象,并且創(chuàng)建唯一的一個。
代碼接近于生活,很有意思。比如一個網(wǎng)站的登錄,點擊登錄后彈出一個登錄彈框,即使再次點擊,也不會再出現(xiàn)一個相同的彈框。又或者一個音樂播放程序,如果用戶打開了一個音樂,又想打開一個音樂,那么之前的播放界面就會自動關(guān)閉,切換到當前的播放界面。這些都是單例模式的應(yīng)用場景。
要實現(xiàn)一個單例模式,一個經(jīng)典的方式是創(chuàng)建一個類,類中又一個方法能創(chuàng)建該類的實例對象,還有一個標記,記錄是否已經(jīng)創(chuàng)了過了實例對象。如果對象已經(jīng)存在,就返回第一次實例化對象的引用。
單例模式的實現(xiàn)
es5實現(xiàn)方式
var Singleton = function(name) {
this.name = name;
//一個標記,用來判斷是否已將創(chuàng)建了該類的實例
this.instance = null;
}
// 提供了一個靜態(tài)方法,用戶可以直接在類上調(diào)用
Singleton.getInstance = function(name) {
// 沒有實例化的時候創(chuàng)建一個該類的實例
if(!this.instance) {
this.instance = new Singleton(name);
}
// 已經(jīng)實例化了,返回第一次實例化對象的引用
return this.instance;
}
用戶可以通過一個廣為人知的接口,對該實例進行訪問。
我們嘗試對該對象進行兩次實例化,觀察兩次實例化結(jié)果是否指向同一個對象。
var a = Singleton.getInstance('sven1');
var b = Singleton.getInstance('sven2');
// 指向的是唯一實例化的對象
console.log(a === b);
返回結(jié)果是:true。說明a、b之間是引用關(guān)系。
es6實現(xiàn)方式
創(chuàng)建Singleton類。class關(guān)鍵字和靜態(tài)函數(shù)都是es6新增的。
class Singleton {
constructor(name) {
this.name = name;
this.instance = null;
}
// 構(gòu)造一個廣為人知的接口,供用戶對該類進行實例化
static getInstance(name) {
if(!this.instance) {
this.instance = new Singleton(name);
}
return this.instance;
}
}
單例模式應(yīng)用實例
我們用一個生活中常見的一個場景來說明單例模式的應(yīng)用。
任意一個網(wǎng)站,點擊登錄按鈕,只會彈出有且僅有一個登錄框,即使后面再點擊登錄按鈕,也不會再彈出多一個彈框。這就是單例模式的典型應(yīng)用。接下來我們實現(xiàn)它。為了注重單例模式的展示,我們把登錄框簡化吧😜
在頁面上設(shè)置一個按鈕
<button id="loginBtn">登錄</button>
為這個按鈕添加點擊事件
const btn = document.getElementById('loginBtn');
btn.addEventListener('click', function() {
loginLayer.getInstance();
}, false);
我們先給一個初始化方法init,在點擊按鈕之后,在頁面上添加一個框框(權(quán)當?shù)卿浛蛄耍?/p>
init() {
var div = document.createElement('div');
div.classList.add('login-layer');
div.innerHTML = "我是登錄浮窗";
document.body.appendChild(div);
}
那么接下來要用單例模式實現(xiàn),點擊按鈕出現(xiàn)有且僅有一個浮窗,方法就是在構(gòu)造函數(shù)中創(chuàng)建一個標記,第一次點擊時創(chuàng)建一個浮窗,用改變標記的狀態(tài),再次點擊按鈕時,根據(jù)標記的狀態(tài)判斷是否要再創(chuàng)建一個浮窗。
上源碼:
class loginLayer {
constructor() {
// 判斷頁面是否已有浮窗的標記
this.instance = null;
this.init();
}
init() {
var div = document.createElement('div');
div.classList.add('login-layer');
div.innerHTML = "我是登錄浮窗";
document.body.appendChild(div);
}
// 靜態(tài)方法作為廣為人知的接口
static getInstance() {
// 根據(jù)標記的狀態(tài)判斷是否要再添加浮窗,如果標記不為空就創(chuàng)建一個浮窗
if(!this.instance) {
this.instance = new loginLayer();
}
return this.instance;
}
}
當然不要忘記為浮窗添加一個樣式,讓浮窗顯示啦
.login-layer {
width: 200px;
height: 200px;
background-color: rgba(0, 0, 0, .6);
text-align: center;
line-height: 200px;
display: inline-block;
}
最后奉上該實例的源碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>單例實現(xiàn)登錄彈窗</title>
<style>
.login-layer {
width: 200px;
height: 200px;
background-color: rgba(0, 0, 0, .6);
text-align: center;
line-height: 200px;
display: inline-block;
}
</style>
</head>
<body>
<button id="loginBtn">登錄</button>
<script>
const btn = document.getElementById('loginBtn');
btn.addEventListener('click', function() {
loginLayer.getInstance();
}, false);
class loginLayer {
constructor() {
this.instance = null;
this.init();
}
init() {
var div = document.createElement('div');
div.classList.add('login-layer');
div.innerHTML = "我是登錄浮窗";
document.body.appendChild(div);
}
static getInstance() {
if(!this.instance) {
this.instance = new loginLayer();
}
return this.instance;
}
}
</script>
</body>
</html>
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
JavaScript實現(xiàn)的搜索及高亮顯示功能示例
這篇文章主要介紹了JavaScript實現(xiàn)的搜索及高亮顯示功能,涉及javascript字符遍歷與頁面元素屬性相關(guān)操作技巧,需要的朋友可以參考下2017-08-08
javascript函數(shù)的call、apply和bind的原理及作用詳解
javascript函數(shù)的call、apply和bind?本質(zhì)是用來實現(xiàn)繼承的,專業(yè)點說法就是改變函數(shù)體內(nèi)部this的指向,當一個對象沒有某個功能時,就可以用這3個來從有相關(guān)功能的對象里借用過來,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下2023-05-05
JavaScript深入淺出__proto__和prototype
這篇文章主要介紹了JavaScript深入淺出__proto__和prototype,文章基于JavaScript的相關(guān)資料展開詳細的內(nèi)容介紹。具有一定的參考價值,需要的小伙伴可以參考一下2022-05-05
JavaScript設(shè)計模式之性能優(yōu)化模式享元模式
這篇文章主要介紹了JavaScript設(shè)計模式之性能優(yōu)化模式享元模式,享元設(shè)計模式是用于性能優(yōu)化的模式,這種設(shè)計模式的核心在于可以共享技術(shù)并支持對大量細分過后的對象進行調(diào)整,更多相關(guān)內(nèi)容需要的小伙伴可以參考一下2022-06-06
前端實現(xiàn)word文檔預(yù)覽和內(nèi)容提取的詳細過程
在前端直接讀取并原樣展示W(wǎng)ord文檔是一個相對復(fù)雜的任務(wù),因為Word文檔的格式(如.doc或.docx)與Web技術(shù)棧使用的格式(HTML、CSS)不兼容,下面這篇文章主要給大家介紹了關(guān)于前端實現(xiàn)word文檔預(yù)覽和內(nèi)容提取的詳細過程,需要的朋友可以參考下2024-05-05

