JS中的單例模式及單例模式原型類的實現

影依賢者發表於2021-07-11

單例模式

單例模式的定義: 保證一個類只有一個例項,並提供一個訪問它的全域性訪問點

通過一個簡單的例子來了解單例模式的作用:

class Div {
    constructor() {
        return document.createElement("div");
    }
}

btn.addEventListener("click", function (event) {
    const div = new Div();
    document.body.appendChild(div);
});

現在頁面上的這個按鈕每被點選一下就會生成一個div,但是現在如果這個div是登入框,我當然就會想要這段函式只生成一個,這時候就可以用到單例模式的思想:讓一個類只會生成一個例項。

在JS裡實現單例模式很簡單,只要使用閉包就能做到,這是使用ES6的class語法實現的單例模式:

let div = null;
class Div {
    constructor() {
        return div ?? (div = document.createElement("div"));
    }
}

這樣,通過閉包實現了單例模式,無論點選多少次按鈕,只會生成一個div。

考慮到單例模式應用的廣泛,我實現了一個原型類,通過繼承該原型類可以直接得到一個單例模式的類:

const SingletonConstructor = (function () {
    const instances = {};
    return class {
        constructor(Constructor) {
            let className = new.target.name;
            if (instances[className]) {
                return instances[className];
            } else {
                let instance = new Constructor();
                Object.setPrototypeOf.call(null, instance, new.target.prototype);
                return (instances[className] = instance);
            }
        }
    };
})();

class Div extends SingletonConstructor {
    constructor() {
        super(function () {
            return document.createElement("div");
        });
    }
}

需要設計為單例的類只需要繼承這個原型類後在建構函式的super中寫入建構函式就能實現單例模式。

相關文章