1、定义
- 把接收多个参数的函数变换成接收一个单一参数的函数(单一参数为多个参数中的第一个)
- 把接收多个参数的函数变换成接收单个参数的多个函数的依次调用(单个参数为多个参数中的第一个)
1)思想:一个JS预处理的思想,降低通用性,提高适用性
2)核心原理:利用函数执行,可以形成一个不销毁的私有作用域,把预先处理的内容都存在这个不销毁的作用域里面,并且返回一个小函数,以后要执行的就是这个小函数。
3)特点:
参数复用 | 需要输入多个参数,最终只需输入一个,其余通过arguments来获取 |
提前返回 | 避免重复去判断某一条件是否符合,不符合则return 不再继续执行下面的操作 |
延迟执行 | 避免重复的去执行程序,等真正需要结果的时候再执行 |
3)例如 add操作:
// 1.常规的add函数
function add(x, y) {
return x + y
}
// 2. 柯里化后
function curryingAdd(x) {
return function (y) {
return x + y
}
}
// 3.调用函数
add(1, 2) // 3
curryingAdd(1)(2) // 3
2、参数复用
对于正则的校验,如果有很多地方都要校验是否有数字,我们只需要将第一个参数验证规则reg进行复用,这样别的地方就能够直接调用hasNumber,hasString等函数,让参数能够复用。
// 1. 函数柯里化之前。每次验证都要输入参数reg
function check(reg, txt){
return reg.test(txt);
}
// 2. 对函数柯里化,实现对 正则参数reg 的复用
function curryingCheck(reg){
return function(txt){
return reg.test(txt);
}
}
// 调用柯里化后的函数
var hasNumber = curryingCheck(/\d+/g); //验证是否包含数字
var hasString = curryingCheck(/[a-z]+/g); //验证是否包含字母
// 复用传入的reg参数
hasNumber('test1'); //true
hasNumber('test') //true
3、 提前返回
对于监听事件的判断则只会走一次,如果是传统函数则会多次执行
- 下面代码var elBind=addEvent() 会先判断一次浏览器的环境,然后返回一个小函数 function(el, sType, fn, capture);
- 之后 elBind(span, 'click', function () {console.log("1")}, false)、elBind(div, 'click', function () {console.log("1")}, false) 均只执行小函数,不会再多次判断浏览器环境。
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);
});
};
}
};
var elBind=addEvent();
var span=document.getElementById("s");
var div=document.getElementById("d");
elBind(span, 'click', function () {console.log("1")}, false)
elBind(div, 'click', function () {console.log("1")}, false)
4、 延迟执行
bind函数实现机制就是柯里化的封装,等需要的时候再执行函数
Function.prototype.bind = function (context) {
var _this = this
var args = Array.prototype.slice.call(arguments, 1)
return function() {
return _this.apply(context, args)
}
}
5、 字节面试题:实现 curry函数, 支持以下功能
// 实现 curry函数, 支持以下功能
var abc = function(a, b, c) {
return [a, b, c];
};
var curried = curry(abc);
curried(1)(2)(3);
// => [1, 2, 3]
curried(1, 2)(3);
// => [1, 2, 3]
curried(1, 2, 3);
// => [1, 2, 3]