一、什么是柯里化?
柯里化(Currying)是一种关于函数的高阶技术。它不仅被用于 JavaScript,还被用于其他编程语言。柯里化是一种函数的转换,它是指将一个函数从可调用的 f(a, b, c)
转换为可调用的 f(a)(b)(c)
。柯里化不会调用函数。它只是对函数进行转换。
维基百科版定义:
简单版定义:
二、柯里化有什么用?
举个例子。
var add = function (x) {
return function (y) {
return x + y;
};
};
var increment = add(1);
var addTen = add(10);
console.log(increment(2)); // 3
console.log(addTen(2)); // 12
这表明curry
是一种“预加载”函数的能力,通过传递一到两个参数调用函数,就能得到一个记住了这些参数的新函数。
再举个例子:有一个用于格式化和输出日志的函数log(date, level, msg)
。在实际项目中,此函数具有很多有用的功能,例如通过网络发送日志等。
function log(date, level, msg) {
console.log(`[${date.getHours()}:${date.getMinutes()}] [${level}] ${msg}`);
}
将它柯里化:
var log = _.curry(log); // 使用 lodash 的 curry 方法
柯里化之后,log仍然可以正常运行:
log(new Date(), 'DEBUG', 'some debug'); // log(a, b, c)
同时,也可以以柯里化的形式调用:
log(new Date())('DEBUG')('some debug'); // log(a)(b)(c)
现在,我们可以轻松地为当前日志创建便捷函数:
// logNow 是一个带有第一个固定参数的偏函数(partial)
logNow = log(new Date());
// 使用它
logNow('INFO', 'some info msg');
// 进而,也可以创建一个为 当前时间 DEBUG 级别的 便捷方法
debugNow = logNow('DEBUG');
// 使用它, 只需要一个参数
debugNow('only msg here');
所以:
-
柯里化之后,我们没有丢失任何东西,如log依然可以正常被调用
-
此外还可以轻松地生成偏函数(
partial function
)
三、实现curry函数
提问:请实现一个函数,实现以下功能:
add(1, 2, 3); // 6
add(1,2)(3); // 6
add(1)(2)(3); // 6
答案:
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function (...args2) {
return curried.apply(this, args.concat(args2));
};
}
};
}
// 另一种实现
function curry(fn) {
return (...args) => {
if (args.length >= fn.length) {
return fn.apply(null, args);
} else {
return curry(fn.bind(null, ...args));
}
};
}
测试一下:
function sum(a, b, c) {
return a + b + c;
}
var curriedSum = curry(sum);
console.log(curriedSum(1, 2, 3)); // 6,正常形式调用
console.log(curriedSum(1, 2)(3)); // 6,以偏函数的方式调用
console.log(curriedSum(1)(2)(3)); // 6,以偏函数的方式调用
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!