JavaScript设计模式是针对常见开发场景总结出的可复用解决方案,能够帮助开发者写出结构更清晰、扩展性更强的代码。常见的JavaScript设计模式可以分为创建型、结构型、行为型三大类,创建型模式主要处理对象创建相关的问题,结构型模式关注类和对象的组合方式,行为型模式则侧重对象之间的通信和职责分配。

常见的JavaScript设计模式分类
创建型模式除了本文要讲的单例模式、工厂模式,还有原型模式、建造者模式等;结构型模式包含适配器模式、装饰器模式、代理模式等;行为型模式有观察者模式、发布订阅模式、策略模式、迭代器模式等。不同的设计模式适用不同的开发场景,开发者可以根据实际需求选择合适的模式使用。
单例模式的实现
单例模式的核心是保证一个类只有一个实例,并且提供一个全局访问点来获取这个实例。在JavaScript中,实现单例模式的方式有很多,最常见的是利用闭包保存唯一实例,或者通过静态属性判断实例是否已经存在。
闭包实现单例模式
这种方式通过立即执行函数创建闭包,把实例保存在闭包变量中,外部无法直接修改这个变量,只能通过暴露的方法获取实例。
// 单例模式闭包实现
const Singleton = (function() {
// 闭包中保存唯一实例,外部无法直接访问
let instance = null;
// 定义单例的构造函数
function SingletonConstructor(name) {
this.name = name;
this.data = [];
}
// 给构造函数添加原型方法
SingletonConstructor.prototype.addData = function(item) {
this.data.push(item);
};
SingletonConstructor.prototype.getData = function() {
return this.data;
};
// 返回获取实例的方法
return function(name) {
// 如果实例不存在则创建,存在则直接返回
if (!instance) {
instance = new SingletonConstructor(name);
}
return instance;
};
})();
// 测试单例模式
const s1 = Singleton('实例1');
const s2 = Singleton('实例2');
console.log(s1 === s2); // 输出true,说明两个变量指向同一个实例
s1.addData('测试数据');
console.log(s2.getData()); // 输出["测试数据"],说明s2和s1共享数据
静态属性实现单例模式
这种方式直接在构造函数上添加静态属性保存实例,每次创建实例前先判断静态属性是否存在,存在则直接返回,不存在则创建并赋值给静态属性。
// 单例模式静态属性实现
function Singleton(name) {
// 判断构造函数的静态属性instance是否存在
if (typeof Singleton.instance === 'object') {
return Singleton.instance;
}
// 不存在则初始化实例属性
this.name = name;
this.list = [];
// 把当前实例赋值给静态属性
Singleton.instance = this;
// 隐式返回this
}
Singleton.prototype.addItem = function(item) {
this.list.push(item);
};
Singleton.prototype.getItems = function() {
return this.list;
};
// 测试
const a = new Singleton('a');
const b = new Singleton('b');
console.log(a === b); // 输出true
a.addItem('item1');
console.log(b.getItems()); // 输出["item1"]
工厂模式的实现
工厂模式的核心是把对象的创建逻辑封装起来,调用者不需要关心对象创建的具体细节,只需要传入对应的参数,工厂就可以返回对应的对象实例。工厂模式可以分为简单工厂模式、工厂方法模式和抽象工厂模式,其中简单工厂模式在JavaScript中应用最为广泛。
简单工厂模式实现
简单工厂模式通过一个工厂函数,根据传入的参数不同,返回不同类型的对象实例,适合创建的对象类型较少的场景。
// 定义不同类型的构造函数
function Person(name, age) {
this.name = name;
this.age = age;
this.type = 'person';
}
Person.prototype.sayHello = function() {
console.log(`我是${this.name},今年${this.age}岁`);
};
function Animal(name, species) {
this.name = name;
this.species = species;
this.type = 'animal';
}
Animal.prototype.makeSound = function() {
console.log(`${this.name}是${this.species}`);
};
// 简单工厂函数
function Factory(type, options) {
switch(type) {
case 'person':
return new Person(options.name, options.age);
case 'animal':
return new Animal(options.name, options.species);
default:
throw new Error('不支持的类型');
}
}
// 使用工厂创建实例
const p = Factory('person', { name: '张三', age: 20 });
p.sayHello(); // 输出我是张三,今年20岁
const dog = Factory('animal', { name: '小狗', species: '犬科' });
dog.makeSound(); // 输出小狗是犬科
工厂方法模式实现
工厂方法模式把对象的创建逻辑延迟到子类或者具体的工厂方法中,每个类型的对象对应一个专门的工厂方法,扩展性比简单工厂模式更好,新增对象类型时不需要修改原有工厂代码。
// 抽象工厂基类
class Factory {
create() {
throw new Error('子类需要实现create方法');
}
}
// 具体产品类
class Car {
constructor(brand) {
this.brand = brand;
}
run() {
console.log(`${this.brand}汽车在行驶`);
}
}
class Bike {
constructor(brand) {
this.brand = brand;
}
ride() {
console.log(`${this.brand}自行车在骑行`);
}
}
// 具体工厂类
class CarFactory extends Factory {
create(brand) {
return new Car(brand);
}
}
class BikeFactory extends Factory {
create(brand) {
return new Bike(brand);
}
}
// 使用工厂方法模式
const carFactory = new CarFactory();
const myCar = carFactory.create('特斯拉');
myCar.run(); // 输出特斯拉汽车在行驶
const bikeFactory = new BikeFactory();
const myBike = bikeFactory.create('捷安特');
myBike.ride(); // 输出捷安特自行车在骑行
两种模式的适用场景
单例模式适合需要全局唯一实例的场景,比如全局状态管理、数据库连接池、日志对象等,避免重复创建实例造成资源浪费。工厂模式适合对象创建逻辑复杂、需要批量创建同类型对象或者需要解耦对象创建和使用的场景,比如组件创建、接口数据适配等场景都可以使用工厂模式简化代码。
JavaScript设计模式单例模式工厂模式修改时间:2026-07-19 07:39:30