单例模式的实现
单例模式的核心目标是确保一个类在全局范围内只有唯一实例,并且提供一个统一的访问入口。在JavaScript中,由于本身没有传统面向对象语言的类概念,我们可以通过闭包或者静态属性来实现单例逻辑。

基于闭包的实现方式
闭包可以保存私有变量,我们可以利用这个特性存储唯一的实例,外部无法直接修改这个实例,只能通过固定的方法获取。
// 单例模式闭包实现
const Singleton = (function() {
// 私有变量存储唯一实例
let instance = null;
// 实际的构造函数,创建实例的逻辑
function createInstance() {
const obj = {
name: '单例实例',
// 示例方法
showInfo: function() {
console.log('当前实例名称:' + this.name);
}
};
return obj;
}
// 返回获取实例的方法
return function() {
// 如果实例不存在则创建
if (!instance) {
instance = createInstance();
}
// 始终返回同一个实例
return instance;
};
})();
// 测试代码
const s1 = Singleton();
const s2 = Singleton();
console.log(s1 === s2); // 输出 true,说明两个引用指向同一个实例
s1.showInfo(); // 输出 当前实例名称:单例实例
基于静态属性的实现方式
我们也可以给构造函数添加静态属性来存储实例,这种方式更贴近传统面向对象语言的实现思路。
// 单例模式静态属性实现
function SingletonClass() {
// 如果已经存在实例,直接返回
if (SingletonClass.instance) {
return SingletonClass.instance;
}
// 初始化实例属性
this.id = Math.random();
this.time = new Date().toLocaleString();
// 保存当前实例到静态属性
SingletonClass.instance = this;
}
// 测试代码
const sc1 = new SingletonClass();
const sc2 = new SingletonClass();
console.log(sc1 === sc2); // 输出 true
console.log(sc1.id === sc2.id); // 输出 true,id相同说明是同一个实例
工厂模式的实现
工厂模式的核心是将对象的创建逻辑封装起来,调用者不需要关心对象具体是怎么实例化的,只需要传入对应的参数,工厂就能返回符合要求的对象。这种模式可以降低代码之间的耦合度,方便后续扩展新的对象类型。
简单工厂模式
简单工厂模式通过一个工厂函数,根据传入的参数判断需要创建的对象类型,返回对应的实例。
// 定义不同的产品类
function ProductA() {
this.name = '产品A';
this.getPrice = function() {
return 100;
};
}
function ProductB() {
this.name = '产品B';
this.getPrice = function() {
return 200;
};
}
// 简单工厂函数
function ProductFactory(type) {
switch(type) {
case 'A':
return new ProductA();
case 'B':
return new ProductB();
default:
throw new Error('不支持的产品类型');
}
}
// 测试代码
const p1 = ProductFactory('A');
const p2 = ProductFactory('B');
console.log(p1.name); // 输出 产品A
console.log(p2.getPrice()); // 输出 200
工厂方法模式
简单工厂模式如果要新增产品类型需要修改工厂内部的判断逻辑,不符合开闭原则。工厂方法模式则将每个产品的创建逻辑放到对应的子工厂中,新增产品时只需要新增子工厂即可。
// 抽象工厂基类
function Factory() {}
Factory.prototype.createProduct = function() {
throw new Error('子类需要实现createProduct方法');
};
// 产品A的工厂
function FactoryA() {}
FactoryA.prototype = new Factory();
FactoryA.prototype.createProduct = function() {
return new ProductA();
};
// 产品B的工厂
function FactoryB() {}
FactoryB.prototype = new Factory();
FactoryB.prototype.createProduct = function() {
return new ProductB();
};
// 测试代码
const fa = new FactoryA();
const productA = fa.createProduct();
console.log(productA.name); // 输出 产品A
const fb = new FactoryB();
const productB = fb.createProduct();
console.log(productB.getPrice()); // 输出 200
两种模式的适用场景
单例模式适合管理全局唯一的资源,比如全局状态管理、数据库连接池、日志工具、缓存对象等场景,避免重复创建带来的资源浪费。
工厂模式适合对象创建逻辑复杂、或者需要根据不同条件创建不同类型对象的场景,比如组件创建、接口返回数据适配、跨平台对象生成等,能够大幅提升代码的可扩展性。
注意事项
- 单例模式如果使用不当,容易造成全局状态污染,建议仅在确实需要全局唯一实例的场景下使用,不要滥用。
- 简单工厂模式适合产品类型较少且变动不频繁的场景,如果产品类型经常新增,建议使用工厂方法模式,避免频繁修改工厂函数。
- JavaScript中的单例模式也可以直接通过对象字面量实现,因为对象字面量本身就是唯一的,适合简单的单例场景。
// 对象字面量实现单例
const simpleSingleton = {
data: {},
setData: function(key, value) {
this.data[key] = value;
},
getData: function(key) {
return this.data[key];
}
};
// 所有引用都指向同一个对象
const s3 = simpleSingleton;
const s4 = simpleSingleton;
s3.setData('test', 123);
console.log(s4.getData('test')); // 输出 123
JavaScript单例模式工厂模式设计模式修改时间:2026-06-14 00:39:35