JavaScript中贯彻单一职责原则(SRP)要求每个函数、对象或类只承担一个明确责任,如UserService只管数据获取、UserRenderer只管视图更新、Logger只管日志写入,通过组合而非堆砌实现职责分离,方法级也需拆分多任务函数,代理与装饰模式天然支持该原则。

在 JavaScript 面向对象编程中贯彻单一职责原则(SRP),核心是让每个函数、对象或类只承担一个明确的、可独立变化的责任——也就是说,它只因一种原因被修改。
把“一件事”拆到最小可维护单元
JavaScript 没有传统 class 的强约束,但 SRP 依然适用。重点不在语法形式,而在职责边界是否清晰。比如一个负责“获取用户数据 + 渲染到页面 + 记录日志”的对象,就违反了 SRP;应拆成:
- UserService:只管从 API 获取、缓存、格式化用户数据
- UserRenderer:只接收数据,生成 DOM 或更新视图
- Logger:只处理日志写入(控制台、文件、远程服务等)
用组合代替大而全的对象
避免在一个构造函数或工厂函数里堆砌多个行为。例如下面这种写法很常见但不推荐:
❌ 不推荐(职责混杂)class UserProfile {
constructor(user) {
this.user = user;
}
// 同时处理验证、保存、通知、UI更新
save() { /* 验证 + 发请求 + 弹提示 + 刷新列表 */ }
}改成组合方式更可控:
立即学习“Java免费学习笔记(深入)”;
class UserProfile {
constructor(user, validator, apiClient, notifier) {
this.user = user;
this.validator = validator;
this.apiClient = apiClient;
this.notifier = notifier;
}
save() {
if (this.validator.isValid(this.user)) {
return this.apiClient.post('/users', this.user)
.then(() => this.notifier.success('保存成功'));
}
}
}方法级别也要守 SRP
一个函数如果做了多件事(比如既解析 JSON 又渲染又错误上报),就该拆分。常见信号包括:
- 函数名含“and”“or”“then”(如
fetchAndRenderUser) - 函数内部有多个 try-catch 块,各自处理不同领域错误
- 参数超过 3 个,且类型/用途差异大
例如将 renderUserCard(data) 拆为:parseUserData(data)、createCardElement(userData)、appendCardTo(container) —— 每个函数只做一件确定的事,测试、复用、调试都更直接。
代理与装饰是天然的 SRP 实践工具
JavaScript 中的代理模式和装饰者模式天然契合 SRP。比如图片加载:
-
MyImage:只负责创建 & 设置
<img>标签 - ProxyImage:只负责预加载逻辑、占位图切换、失败回退
两者解耦后,改加载策略不影响渲染结构,换 DOM 结构也不影响加载流程。这种分离不是为了炫技,而是让每次改动只在一个点发生。



















