单例模式(Singleton Pattern)是一种常用的设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。
单例模式的核心特点
- 唯一性:确保一个类只有一个实例存在
- 全局访问:提供全局访问该实例的方法
- 延迟实例化:通常只在第一次使用时创建实例
JavaScript 实现单例模式的几种方式
1. 对象字面量实现(最简单的单例)
const singleton = {
property: "value",
method: function() {
console.log("I am a method");
}
};
这本质上就是一个单例,因为对象字面量在JavaScript中本身就是唯一的。
2. 使用闭包和立即执行函数(IIFE)
const Singleton = (function() {
let instance;
function createInstance() {
const object = new Object("I am the instance");
return object;
}
return {
getInstance: function() {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true
3. ES6 Class 实现
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this;
}
return Singleton.instance;
}
static getInstance() {
if (!this.instance) {
this.instance = new Singleton();
}
return this.instance;
}
}
const instance1 = new Singleton();
const instance2 = new Singleton();
const instance3 = Singleton.getInstance();
console.log(instance1 === instance2); // true
console.log(instance1 === instance3); // true
4. 模块化的单例模式
在现代JavaScript中,使用ES6模块系统可以更简单地实现单例:
// singleton.js
let instance;
class MySingleton {
constructor() {
if (instance) {
throw new Error("You can only create one instance!");
}
instance = this;
}
// 其他方法...
}
const singletonInstance = Object.freeze(new MySingleton());
export default singletonInstance;
然后在使用时:
import singletonInstance from './singleton.js';
单例模式的应用场景
- 全局状态管理:如Redux中的store
- 配置对象:应用中只需要一个配置对象
- 缓存系统:全局共享的缓存
- 日志系统:应用中只需要一个日志记录器
- 数据库连接池:通常只需要一个连接池实例
单例模式的优缺点
优点:
- 延迟初始化(节省资源)
- 严格控制实例数量
- 全局访问方便
缺点:
- 全局状态可能导致代码耦合
- 难以测试(因为全局状态)
- 可能违反单一职责原则
单例模式在JavaScript中非常常见,但需要谨慎使用,避免过度使用导致代码难以维护。