函数柯里化
函数柯里化有三个特点,参数复用,提前返回,延迟执行,它实际上只是一种思想,没有固定的写法
参数复用
参数复用,简单来说,就是将多个参数变成一个参数,这么做的形式有很多种,下面举个例子
function add(...rest){
let sum = 0;
for(let i =0;i<rest.length;i++){
sum+=rest[i];
}
return sum;
}
add(1,2,3,4)
function curry(fn){
let args = [];
return function cb(){
if(arguments.length<1){
return fn.apply(this,args)
}else{
args=[...args,...arguments]
return cb
}
}
}
cAdd = curry(add)
cAdd(1)(2)(3)(4)()
这里将多个参数的累加修改成一个参数,最后无参数时返回结果
提前返回
提前返回,指的是,提前对一些判断进行返回,有的判断在一次判断后,就不需再判断了,比如下面这个红宝书中的创建XMLHTTPRequest对象的方法
function createXMLHTTPRequest() {
var xmlHttpRequest;
if (window.XMLHttpRequest) {
xmlHttpRequest = new XMLHttpRequest();
if (xmlHttpRequest.overrideMimeType) {
xmlHttpRequest.overrideMimeType("text/xml");
}
} else if (window.ActiveXObject) {
var activexName = [ "MSXML2.XMLHTTP", "Microsoft.XMLHTTP" ];
for ( var i = 0; i < activexName.length; i++) {
try {
xmlHttpRequest = new ActiveXObject(activexName[i]);
if(xmlHttpRequest){
break;
}
} catch (e) {
}
}
}
return xmlHttpRequest;
}
使用这个方法,每次都要对其进行一次判断,将其改为
function createXMLHTTPRequestCurry() {
var xmlHttpRequest;
if (window.XMLHttpRequest) {
return function(){
xmlHttpRequest = new XMLHttpRequest();
if (xmlHttpRequest.overrideMimeType) {
xmlHttpRequest.overrideMimeType("text/xml");
}
return xmlHttpRequest
}
} else if (window.ActiveXObject) {
return function(){
var activexName = [ "MSXML2.XMLHTTP", "Microsoft.XMLHTTP" ];
for ( var i = 0; i < activexName.length; i++) {
try {
xmlHttpRequest = new ActiveXObject(activexName[i]);
if(xmlHttpRequest){
break;
}
} catch (e) {
}
}
return xmlHttpRequest;
}
}
return function(){
return;
}
}
createXMLHTTPRequest=createXMLHTTPRequestCurry()
这样除了第一次的判断外,后面都不再判断,直接执行判断后的内容
延迟执行
延迟执行实际上就是当我们调用这个方法时,不会立即执行,或者说在参数符合规定的时候才会执行我们真正想执行的内容
如上面参数复用中的
cAdd(1)(2)(3)(4)()
在传入1 2 3 4的时候,函数并没有执行加法运算,只是将这个值推入队列中,仅当不传入参数时,才真正执行