通俗说:柯里化就是把add函数的x,y两个参数变成了先用一个函数接收x然后返回一个函数去处理y参数。
// 普通的add函数
function add(x, y) {
return x + y
}
// 柯里化后
function curryingAdd(x) {
return function (y) {
return x + y
}
}
add(1, 2) // 3
curryingAdd(1)(2) // 3
function add(a) {
return function(b) {
return a + b
}
}
等价于:
let add = a => b => a + b
好处、为什么这么用:
- 可以实现参数复用
// 正常正则验证字符串 reg.test(txt)
unction check(reg, txt) {
return reg.test(txt)
}
check(/\d+/g, 'test') //false
check(/[a-z]+/g, 'test') //true
// Currying后
function curryingCheck(reg) {
return function(txt) {
return reg.test(txt)
}
}
var hasNumber = curryingCheck(/\d+/g)
var hasLetter = curryingCheck(/[a-z]+/g)
hasNumber('test1') // true
hasNumber('testtest') // false
hasLetter('21212') // false
上面的示例是一个正则的校验,正常来说直接调用check函数就可以了,但是如果我有很多地方都要校验是否有数字,其实就是需要将第一个参数reg进行复用,这样别的地方就能够直接调用hasNumber,hasLetter等函数,让参数能够复用,调用起来也更方便。
2、提前执行一些代码,
比如:
var addEvent = (function(){
if (window.addEventListener) {
return function(el, sType, fn, capture) {
el.addEventListener(sType, function(e) {
fn.call(el, e);
}, (capture));
};
} else if (window.attachEvent) {
return function(el, sType, fn, capture) {
el.attachEvent("on" + sType, function(e) {
fn.call(el, e);
});
};
}
})();
这段代码中的判断语句会提前执行,且只会执行一次,就避免了我们每次调用方法都会进入这个 if else, 初始addEvent的执行其实值实现了部分的应用(只有一次的if…else if…判定),而剩余的参数应用都是其返回函数实现的
参考链接:https://www.zhangxinxu.com/wordpress/2013/02/js-currying/
3、延迟计算:
ES5中的bind方法,用来改变Function执行时候的上下文(函数主体本身不执行,与call/apply直接执行并改变不同),而是返回一个新的函数。本质上就是延迟执行。
var obj = {
"name": "currying"
},
fun = function() {
console.log(this.name);
}.bind(obj);
fun(); // currying
从IE6~8的自定义扩展来看,其实现的机制就是柯里化(不考虑执行时的新增参数):
if (!function() {}.bind) {
Function.prototype.bind = function(context) {
var self = this
, args = Array.prototype.slice.call(arguments);
return function() {
return self.apply(context, args.slice(1));
}
};
}
个人理解:
函数柯里化:就是在一个函数里边再return一个函数,里边的函数主要用于依赖参数去实现一些逻辑操作,或者延迟去执行;外边的函数可以去接受一个公共的参数,或者提前去执行实现一些业务逻辑