推荐答案
// www.javascriptcn.com code example
class Singleton {
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
Singleton.instance = this;
this.data = 'Initial Data'; // 示例数据
}
getData() {
return this.data;
}
setData(newData) {
this.data = newData;
}
}
// 使用示例
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true
console.log(instance1.getData()); // Initial Data
instance2.setData('Updated Data');
console.log(instance1.getData()); // Updated Data本题详细解读
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在JavaScript中,可以使用多种方法实现单例模式。上述推荐答案展示了使用静态属性在类内部维护实例的常见方法,下面详细解析其原理和实现步骤:
静态属性
instance: 类Singleton内部定义了一个静态属性instance,用于存储唯一的实例。初始值为undefined。构造函数中的逻辑: 构造函数
constructor是实现单例模式的关键。- 检查实例是否存在: 首先,它检查
Singleton.instance是否已经存在(即是否已经创建过实例)。如果已经存在,则直接返回已有的实例,而不会创建新的实例。 - 创建并存储实例: 如果
Singleton.instance不存在,则创建当前类的实例,并将其赋值给Singleton.instance,同时初始化一些实例数据。
- 检查实例是否存在: 首先,它检查
实例方法
getData和setData: 这两个方法提供了访问和修改单例实例内部数据的方法,它们是实例的方法,而非类的方法。使用示例: 通过
new Singleton()创建两个实例instance1和instance2。因为单例模式的特性,这两个变量实际上引用的是同一个实例。instance1 === instance2返回true,验证了只有一个实例。- 对一个实例的数据进行修改,另一个实例的数据也会同步更新,因为它们是同一个实例。
为什么使用这种方式实现单例模式?
- 控制实例数量: 保证了在整个应用程序中只有一个实例存在,避免了资源浪费和状态不一致问题。
- 全局访问点: 通过
Singleton.instance可以方便地在任何地方访问这个唯一的实例。 - 惰性初始化: 只有在第一次调用
new Singleton()时才会创建实例,提高了程序的性能,避免了不必要的资源消耗。
其他实现单例模式的方式:
除了使用类的静态属性,还可以使用闭包等方式实现单例模式,例如:
// www.javascriptcn.com code example
const Singleton = (function() {
let instance;
return function() {
if (instance) {
return instance;
}
instance = this;
this.data = 'Initial Data'; // 示例数据
return instance;
};
})();
//使用方式相同
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true
console.log(instance1.data); // Initial Data
instance2.data = 'Updated Data';
console.log(instance1.data); // Updated Data
这种方式使用了立即执行函数表达式(IIFE)创建了一个闭包,利用闭包来保存 instance 变量。