es6實現單例模式及其應用

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

單例模式能在合適的時候建立對象,而且建立惟一的一個。
代碼接近於生活,頗有意思。好比一個網站的登陸,點擊登陸後彈出一個登陸彈框,即便再次點擊,也不會再出現一個相同的彈框。又或者一個音樂播放程序,若是用戶打開了一個音樂,又想打開一個音樂,那麼以前的播放界面就會自動關閉,切換到當前的播放界面。這些都是單例模式的應用場景。
要實現一個單例模式,一個經典的方式是建立一個類,類中又一個方法能建立該類的實例對象,還有一個標記,記錄是否已經創了過了實例對象。若是對象已經存在,就返回第一次實例化對象的引用。es6

單例模式的實現

es5實現方式

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;
}

用戶能夠經過一個廣爲人知的接口,對該實例進行訪問。
咱們嘗試對該對象進行兩次實例化,觀察兩次實例化結果是否指向同一個對象。app

var a = Singleton.getInstance('sven1');
var b = Singleton.getInstance('sven2');
// 指向的是惟一實例化的對象
console.log(a === b);

返回結果是:true。說明a、b之間是引用關係。函數

es6實現方式

建立Singleton類。class關鍵字和靜態函數都是es6新增的。網站

class Singleton {
    constructor(name) {
        this.name = name;
        this.instance = null;
    }
    // 構造一個廣爲人知的接口,供用戶對該類進行實例化
    static getInstance(name) {
        if(!this.instance) {
            this.instance = new Singleton(name);
        }
        return this.instance;
    }
}

單例模式應用實例

咱們用一個生活中常見的一個場景來講明單例模式的應用。
任意一個網站,點擊登陸按鈕,只會彈出有且僅有一個登陸框,即便後面再點擊登陸按鈕,也不會再彈出多一個彈框。這就是單例模式的典型應用。接下來咱們實現它。爲了注重單例模式的展現,咱們把登陸框簡化吧😜


在頁面上設置一個按鈕ui

<button id="loginBtn">登陸</button>

爲這個按鈕添加點擊事件this

const btn = document.getElementById('loginBtn');
btn.addEventListener('click', function() {
    loginLayer.getInstance();
}, false);

咱們先給一個初始化方法init,在點擊按鈕以後,在頁面上添加一個框框(權當登陸框了)es5

init() {
    var div = document.createElement('div');
    div.classList.add('login-layer');
    div.innerHTML = "我是登陸浮窗";
    document.body.appendChild(div);
}

那麼接下來要用單例模式實現,點擊按鈕出現有且僅有一個浮窗,方法就是在構造函數中建立一個標記,第一次點擊時建立一個浮窗,用改變標記的狀態,再次點擊按鈕時,根據標記的狀態判斷是否要再建立一個浮窗。
上源碼:code

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;
    }
}

固然不要忘記爲浮窗添加一個樣式,讓浮窗顯示啦htm

.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>單例實現登陸彈窗</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>
相關文章
相關標籤/搜索