柯里化:把接受多个参数的函数变换成接收一个单一参数(最初函数的第一个参数)的函数,并且返回接收余下的参数而且返回结果的新函数的技术
柯里化的通用实现方法: 1 2 3 4 5 6 7 8 9 10 11 12 const curry=(fn,...args )=> { return args.length<fn.length ?(..._args )=> curry(fn,...args,..._args) :fn(...args) } function add1 (a,b,c,d ) { return a+b+c+d; } var add=curry(add1)console .log(add(1 ,2 ,3 ,4 ))console .log(add(1 )(2 )(3 )(4 ));console .log(add(1 ,2 )(3 ,4 ));
柯里化的作用: 参数复用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 function check (reg, txt ) { return reg.test(txt) } check(/\d+/g , 'test' ) check(/[a-z]+/g , 'test' ) function curryingCheck (reg ) { return function (txt ) { return reg.test(txt) } } var hasNumber = curryingCheck(/\d+/g )var hasLetter = curryingCheck(/[a-z]+/g )hasNumber('test1' ) hasNumber('testtest' ) hasLetter('21212' )
第一个参数reg进行了复用
提前返回 举个例子,兼容现代浏览器以及IE浏览器的事件添加方法,我们正常情况可能这样写:
1 2 3 4 5 6 7 8 9 10 11 12 var addEvent=function (el,type,fn,capture ) { if (window .addEventListener){ el.addEventListener(type,function (e ) { fn.call(el,e); },capture); } else if (window .attachEvent){ el.attachEvent("on" +type,function (e ) { fn.call(el,e); }) } }
上面的方法我们每次使用addEvent为元素添加事件的时候,都会走一遍if…else if…,其实只要判断一次,用柯里化
1 2 3 4 5 6 7 8 9 10 11 12 var addEvent=(function ( ) { if (window .addEventListener){ el.addEventListener(type,function (e ) { fn.call(el,e); },capture); } else if (window .attachEvent){ el.attachEvent("on" +type,function (e ) { fn.call(el,e); }) } })();
延迟执行 比如bind方法的实现机制就是柯里化:
1 2 3 4 5 6 7 Function .prototype.bind=function (context ) { var self=this ; var args=Array .prototype.slice.call(arguments ,1 ); return funtion ( ) { return self.apply(context,args); } }
参考文章:
https://juejin.cn/post/6844904093467541517
https://www.zhangxinxu.com/wordpress/2013/02/js-currying/
https://www.jianshu.com/p/2975c25e4d71