这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
五、柯里化
柯里化(Currying)是把接受多个参数的函数转变为单一参数的函数,并且返回接受余下的参数且返回结果的新函数的技术。
简单来说:
- 通过闭包管理
- 支持链式调用
- 每次运行返回一个 function
即:通过将多个参数换成一个参数,每次运行返回新函数的技术
5.1 柯里化举例
// 普通的 add 函数
function add (a, b) {
return a + b;
}
add(1, 2);
复制代码
// 柯里化函数
function curryingAdd (x) {
return function(y) {
return x + y;
}
}
curryingAdd(x)(y);
复制代码
5.2 柯里化好处
- 参数复用
- 提前确认
- 延迟运行
// 校验数字
let numberReg = /[0-9]+/g;
// 校验小写字母
let stringReg = /[a-z]+/g;
// currying 后
function curryingCheck(reg) {
return function(txt) {
return reg.test(txt);
}
}
let checkNumber = curryingCheck(numberReg);
let checkString = curryingCheck(stringReg);
console.log(checkNumber('13888888888')); // true
console.log(checkString('jsliang')); // true
复制代码
5.3 柯里化实现 add(1)(2)(3)
// 实现一个 add 方法,使计算结果能够满足以下预期
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;
复制代码
function add () {
const numberList = Array.from(arguments);
// 进一步收集剩余参数
const calculate = function() {
numberList.push(...arguments);
return calculate;
}
// 利用 toString 隐式转换,最后执行时进行转换
calculate.toString = function() {
return numberList.reduce((a, b) => a + b, 0);
}
return calculate;
}
// 实现一个 add 方法,使计算结果能够满足以下预期
console.log(add(1)(2)(3)); // 6
console.log(add(1, 2, 3)(4)); // 10;
console.log(add(1)(2)(3)(4)(5)); // 15;
console.log(add(1)(2)(3)(4)(5, 6, 7)); // 28
复制代码
5.4 柯里化实现 compose(foo, bar, baz)(‘start’)
function foo(...args) {
console.log(args[0]);
return 'foo';
}
function bar(...args) {
console.log(args[0]);
return 'bar';
}
function baz(...args) {
console.log(args[0]);
return 'baz';
}
function compose() {
// 闭包元素 - 函数列表
const list = Array.from(arguments);
// 闭包元素 - 函数列表执行位置
let index = -1;
// 闭包元素 - 上一个函数的返回
let prev = '';
// 返回闭包函数
const doNext = function() {
index++; // 索引值累加
// 一开始没有上一个元素时,获取第二个括号的值
if (!prev) {
prev = arguments[0];
}
// 设置前一个结果为当前函数返回
prev = list[index](prev);
// 递归调用
if (index < list.length - 1) {
doNext(index + 1);
}
};
// 第一次返回闭包函数
return doNext;
}
compose(foo, bar, baz)('start');
复制代码
相关好文
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END