这是我参与更文挑战的第9天,活动详情查看:更文挑战
首先说一下为什么叫柯里化,完全是因为这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的。所以不必在意为什么叫这个名字,我们也可以记谐音颗粒化(将参数一个一个的传入)。
这个就是把接收多个参数的方法变换成接收单一参数的函数,并且返回接收剩余参数的一个新函数。
函数
先来看一个简单的函数
function multiply(x, y){
return x * y;
}
multiply(2, 5); // 10
上面这个函数的主要作用就是将两个函数相乘。 接下来我们让这个函数变成只接受一个参数的函数,并且可以保存之前传入的值。
function curry_multiply(x, y) {
return (y) => {
return x * y;
}
}
let multiply2 = curry_multiply(2);
multiply2(5); // 10
let multiply5 = curry_multiply(5);
multiply5(2); // 10
了解过闭包的就应该能看懂上面的函数,返回了一个新的函数,并且保存了x变量的值。这就使得我们传入curry_multiply的值可以保留下来,方便我们针对不同情况的调用。
下面介绍一个通用柯里化的函数,此函数只是一个简化版本,在实际应用中需要判断其他情况。
function curry(fn, ...args) {
return (...arg) => {
return fn(...args, ...arg);
}
}
function volumn(x, y, z) {
return x*y*z;
}
let test2 = curry(volumn, 2);
let test10 = curry(test2, 5);
test10(10); // 100
curry函数的主要作用是将传入的第一个参数作为函数进行调用,将第二个参数作为fn的参数传入,并将剩余参数传入。这样我们可以简单的复用同一个函数的不同参数情况。
应用场景
用的比较多的就是可以复用大多数相似的函数功能,多参数的情况,可以封装一些多次用到的固有参数。
function checkPhone(phoneNumber) {
return /^1[34578]\d{9}$/.test(phoneNumber);
}
function checkEmail(email) {
return /^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/.test(email);
}
上面这种应该在项目里面比较常见,可以用curry稍微优化一下。
let _check = createCurry(check);
let checkPhone = _check(/^1[34578]\d{9}$/);
let checkEmail = _check(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/);