柯里化,即Currying,可以是函数变得更加灵活。我们可以一次性传入多个参数调用它;也可以只传入一部分参数来调用它,让它返回一个函数去解决剩下的参数。
var add = function(x) { return function(y) { return x + y; };};console.log(add(1)(1)); // 输出2var add1 = add(1);console.log(add1(1)); // 输出2var add10 = add(10);console.log(add10(1)); // 输出11代码中,我们可以一次性传入2个1作为参数add(1)(1),也可以传入1个参数之后获取add1与add10函数,这样使用起来非常灵活。
在实际项目中,柯里化通常有以下三大作用
- 参数复用
- 提前确认
- 推迟运行
一、参数复用
所谓参数复用,就是利用闭包的原理,让我们前面传输过来的参数不要被释放掉。看一下下面这段代码就显而易见了:
// 正常封装check函数进行字符串正则匹配function check(reg, txt) { return reg.test(txt)}check(/\d+/g, 'test') //falsecheck(/[a-z]+/g, 'test') //true// 使用柯里化函数进行字符串正则匹配function curryingCheck(reg) { return function (txt) { return reg.test(txt) }}var hasNumber = curryingCheck(/\d+/g)var hasLetter = curryingCheck(/[a-z]+/g)hasNumber('test1') // truehasNumber('testtest') // falsehasLetter('21212') // false二、 提前确认
这一特性经常是用来对浏览器的兼容性做出少量判断并初始化api,比方说我们目前用来监听事件大部分情况是使用addEventListener来实现的,但是少量较久的浏览器并不支持该方法,所以在使用之前,我们可以先做一次判断,之后便可以省略这个步骤了。
var on = (function () { if (document.addEventListener) { return function (element, event, handler) { if (element && event && handler) { element.addEventListener(event, handler, false); } }; } else { return function (element, event, handler) { if (element && event && handler) { element.attachEvent('on' + event, handler); } }; }})();三、 推迟运行
js中的bind这个方法,用到的就是柯里化的这个特征。
Function.prototype.bind = function (context) { var _this = this var args = Array.prototype.slice.call(arguments, 1) return function() { return _this.apply(context, args) }}