1. 什么是单例模式?
单例模式是一种软件设计模式,它可以确保一个类只有一个实例,并提供全局访问点来访问该实例。
在JavaScript中,可以使用单例模式来确保只能创建一个特定对象的实例。这在许多情况下是有用的,例如:
全局配置对象
日志记录器
唯一的用户引导程序(例如,只能存在一个登录框)
2. 实现单例模式的方法
2.1 使用闭包
一个简单的实现单例模式的方法是使用闭包。
const mySingleton = (function() {
let instance;
function init() {
// 私有方法和变量
function privateMethod() {
console.log('I am private');
}
let privateVariable = 'I am also private';
// 公有方法和变量
return {
publicMethod: function() {
console.log('The public can see me!');
},
publicProperty: 'I am also public',
getPrivateVariable: function() {
return privateVariable;
},
setPrivateVariable: function(value) {
privateVariable = value;
}
};
}
return {
getInstance: function() {
if (!instance) {
instance = init();
}
return instance;
}
};
})();
const singletonA = mySingleton.getInstance();
const singletonB = mySingleton.getInstance();
console.log(singletonA === singletonB); // true
这个实现中,我们使用了一个 IIFE(立即调用函数表达式)来创建一个私有作用域来存储实例。init函数只在第一次创建实例时调用一次,并返回一个对象字面量,公开了一些公共方法和变量。getInstance函数确保只有一个实例被创建,并提供对该实例的全局访问点。
2.2 ES6类的静态方法
在ES6中,我们可以使用类构造函数和静态方法来实现单例模式。
class mySingleton {
static instance;
constructor() {
if (mySingleton.instance) {
return mySingleton.instance;
}
// 私有方法和变量
function privateMethod() {
console.log('I am private');
}
let privateVariable = 'I am also private';
// 公有方法和变量
this.publicMethod = function() {
console.log('The public can see me!');
};
this.publicProperty = 'I am also public';
this.getPrivateVariable = function() {
return privateVariable;
};
this.setPrivateVariable = function(value) {
privateVariable = value;
};
mySingleton.instance = this;
}
static getInstance() {
if (!mySingleton.instance) {
mySingleton.instance = new mySingleton();
}
return mySingleton.instance;
}
}
const singletonA = new mySingleton();
const singletonB = new mySingleton();
console.log(singletonA === singletonB); // true
const singletonC = mySingleton.getInstance();
const singletonD = mySingleton.getInstance();
console.log(singletonC === singletonD); // true
在这里,我们使用了ES6类的静态方法来存储和访问实例。构造函数中,我们先检查是否已经有一个实例存在,并如果有,直接返回该实例。如果不存在,就创建一个新的实例。getInstance静态方法确保只有一个实例被创建,并提供对该实例的全局访问点。
3. 总结
单例模式是一种非常有用的设计模式,它可确保一个类只有一个实例,并提供全局访问点来访问该实例。在JavaScript中,我们可以使用闭包或ES6类的静态方法来实现单例模式。
需要注意的是,单例模式可以使代码更易于扩展,也可以使代码更困难,取决于实现的方式。因此,在考虑使用单例模式时,请牢记其优缺点,以确保使用正确的方式。