柯里化通过外层函数预置依赖(如db、logger)并返回只接收业务输入的内层函数,实现可复用、易测试、低耦合的纯函数逻辑,天然支持中间件配置化与单元测试。

JavaScript 中可以通过柯里化把依赖“预置”进函数,形成可复用、易测试、低耦合的业务逻辑单元。这不是框架黑盒,而是利用函数一等公民 + 闭包的自然表达。
柯里化注入的核心结构
把依赖作为第一组参数传入,返回一个只接收业务输入的函数:
- 外层函数接收依赖对象(如 db、logger、config)
- 内层函数接收运行时数据(如 userId、payload)
- 整个链路是纯函数:无副作用、可缓存、可组合
实际写法示例
比如一个获取用户详情的服务:
const fetchUser = (deps) => (userId) => {
return deps.db.find('users', { id: userId })
.then(user => {
deps.logger.info(`Fetched user ${userId}`);
return user;
});
};
// 使用时注入真实依赖
const productionFetch = fetchUser({
db: new DatabaseConnection(),
logger: console
});
// 测试时注入 mock
const testFetch = fetchUser({
db: { find: jest.fn().mockResolvedValue({ id: 1, name: 'Alice' }) },
logger: { info: jest.fn() }
});
结合中间件场景的灵活用法
在 Node.js 或 Koa/Express 中,常用于配置化中间件:
立即学习“Java免费学习笔记(深入)”;
- 用柯里化封装通用逻辑(如日志、鉴权、限流)
- 不同路由或环境传入不同配置,复用同一份逻辑
- 避免每个中间件都手动解构 req.app.locals 或 ctx.state
例如:
const authMiddleware = (options) => (req, res, next) => {
const { requiredRole = 'user', failRedirect = '/login' } = options;
if (!req.user || req.user.role !== requiredRole) {
return res.redirect(failRedirect);
}
next();
};
app.use('/admin', authMiddleware({ requiredRole: 'admin' }));
app.use('/api', authMiddleware({ requiredRole: 'api-user' }));
为什么比传统构造函数注入更轻量
它不依赖容器注册、反射或装饰器,适合中小型项目和函数式风格开发:
- 零运行时开销:编译期确定类型(TypeScript 下可精准推导)
- 无隐藏依赖:所有依赖显式出现在调用处,不靠约定或上下文隐式查找
- 天然支持单元测试:直接传入任意 mock 对象,无需启动容器或模拟全局状态
- 便于组合:多个柯里化函数可 pipe 或 compose,构建声明式处理链


















