单例模式实现
描述
单例模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点。
核心原理
- 构造函数私有化(禁止外部 new)
- 类内部创建唯一实例
- 提供全局访问方法
实现方式
1. 懒汉式(延迟加载)
js
class Singleton {
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
Singleton.instance = this;
this.data = [];
}
getData() {
return this.data;
}
}
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true2. 饿汉式(立即加载)
js
class Singleton {
constructor() {
this.data = [];
}
getData() {
return this.data;
}
}
Singleton.instance = new Singleton();
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true3. 闭包版(推荐)
js
class Singleton {
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
this.data = [];
Singleton.instance = this;
}
getData() {
return this.data;
}
}
// 或使用闭包实现私有变量
const Singleton = (function () {
let instance;
function createInstance() {
const obj = new Object();
obj.data = [];
obj.getData = function () {
return this.data;
};
return obj;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
},
};
})();
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true4. 代理模式版
js
class Singleton {
constructor() {
this.data = [];
}
}
const ProxySingleton = (function () {
let instance;
return function () {
if (!instance) {
instance = new Singleton();
}
return instance;
};
})();
const instance1 = new ProxySingleton();
const instance2 = new ProxySingleton();
console.log(instance1 === instance2); // true5. ES6 符号版
js
const INSTANCE = Symbol("instance");
class Singleton {
constructor() {
if (!Singleton[INSTANCE]) {
this.data = [];
Singleton[INSTANCE] = this;
}
return Singleton[INSTANCE];
}
}
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true实际应用
Redux Store(单例模式应用)
js
let store;
function createStore(reducer, initialState) {
if (store) {
throw new Error("A store already exists");
}
store = {
state: initialState,
listeners: [],
getState() {
return this.state;
},
dispatch(action) {
this.state = reducer(this.state, action);
this.listeners.forEach((listener) => listener());
},
subscribe(listener) {
this.listeners.push(listener);
return () => {
this.listeners = this.listeners.filter((l) => l !== listener);
};
},
};
return store;
}模态框管理
js
class ModalManager {
constructor() {
if (ModalManager.instance) {
return ModalManager.instance;
}
this.modals = new Map();
ModalManager.instance = this;
}
open(id, content) {
if (this.modals.has(id)) {
return this.modals.get(id);
}
const modal = this.createModal(content);
this.modals.set(id, modal);
return modal;
}
close(id) {
if (this.modals.has(id)) {
this.modals.get(id).remove();
this.modals.delete(id);
}
}
createModal(content) {
const modal = document.createElement("div");
modal.innerHTML = content;
document.body.appendChild(modal);
return modal;
}
}
const modalManager = new ModalManager();单例 vs 静态类
| 特性 | 单例模式 | 静态类 |
|---|---|---|
| 实例化 | 延迟/立即 | 不可实例化 |
| 继承 | 可继承、多态 | 不可继承 |
| 实现方式 | 类实例 | 类本身 |
| 内存 | 单一实例 | 按需加载 |
| 线程安全 | 需要处理 | 自动安全 |