JavaScript 函数柯里化(Currying)
函数柯里化是一种将多参数函数转换为一系列单参数函数的技术。它通过部分应用函数参数来创建新的函数。
基本概念
柯里化的基本形式是将 f(a, b, c) 转换为 f(a)(b)(c)。
// 普通函数
function add(a, b, c) {
return a + b + c;
}
// 柯里化版本
function curriedAdd(a) {
return function(b) {
return function(c) {
return a + b + c;
}
}
}
add(1, 2, 3); // 6
curriedAdd(1)(2)(3); // 6
实现柯里化的通用方法
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
}
}
};
}
// 使用示例
const curriedAdd = curry(add);
curriedAdd(1)(2)(3); // 6
应用场景
1. 小程序中的应用
- 参数预配置: 在小程序中,可以预先配置一些通用参数
// 请求API的柯里化版本
const request = curry(function(url, method, data) {
return wx.request({ url, method, data });
});
const get = request('https://api.example.com')('GET');
const post = request('https://api.example.com')('POST');
// 使用预配置的方法
get({ id: 123 }); // 发起GET请求
post({ name: 'John' }); // 发起POST请求
- 事件处理: 预置事件处理函数的参数
const handleEvent = curry(function(eventName, component, event) {
// 处理事件
});
const handleTap = handleEvent('tap');
const handleInput = handleEvent('input');
// 在组件中使用
handleTap(this)(event);
2. 后台管理系统中的应用
- 权限校验: 创建有权限校验的函数
const checkPermission = curry(function(permission, user, action) {
if (user.permissions.includes(permission)) {
action();
} else {
console.log('无权限');
}
});
const checkAdmin = checkPermission('admin');
const checkEditor = checkPermission('editor');
// 使用
checkAdmin(currentUser)(() => {
// 只有管理员能执行的操作
});
- 表单验证: 创建可复用的验证器
在这里插入代码片const validate = curry(function(rule, value) {
return rule.test(value);
});
const validateEmail = validate(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
const validatePhone = validate(/^1[3-9]\d{9}$/);
// 使用
validateEmail('test@example.com'); // true
validatePhone('13800138000'); // true
- API调用: 创建特定资源的CRUD函数
const resourceAPI = curry(function(baseUrl, resource, action, data) {
return axios[action](`${baseUrl}/${resource}`, data);
});
const api = resourceAPI('https://api.example.com');
const userAPI = api('user');
// 使用
userAPI('get')({ id: 1 }); // 获取用户
userAPI('post')({ name: 'John' }); // 创建用户
柯里化的优势
-
参数复用: 可以固定部分参数,生成更具体的函数
-
延迟执行: 可以分步传入参数,在需要时才执行
-
函数组合: 便于进行函数组合,创建更复杂的功能
-
提高代码复用性: 通过部分应用创建可复用的函数变体
注意事项
- 柯里化会增加一定的性能开销(创建多个嵌套函数)
- 不是所有场景都适合柯里化,过度使用可能使代码难以理解
- 在需要处理可变参数函数时,柯里化实现会变得复杂