函数柯里化

函数柯里化

什么是函数柯里化

在计算机可科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

柯里化快速入门

接下来,我们来通过一个例子来体会一下柯里化。
现有一个求两个数之和函数:

function add(a,b){
  return a + b;
}

将add函数柯里化变成:

function addCurrying(a){
  return  function (b){
    return a + b;
  }
}

可以看出,函数addCurrying接受原函数的第一个参数,并且返回了一个接受余下参数的函数,利用了闭包的特性存储了a的值。所以我们通过上面的代码示例,我们能够了解到柯里化函数的特点:
1、一个柯里化的函数首先会接受一下参数,接受了这些参数之后该函数并不会立即求值,而是返回了另一个函数,刚接受的参数会在函数形成的闭包中保存下来。
2、等到函数需要被真正求值时即原函数所需参数全部接收完,会对闭包中存储的数据一并求值。

函数柯里化的实际应用

通过上面的例子,我们体验到了什么是柯里化函数。

但是问题来了,费了这么大劲封装一层,到底有什么用处呢

没有好处想让我们程序员多干事情是不可能滴,这辈子都不可能

所以接下来我们就来看一下函数柯里化的二个实际应用。

参数复用

就是将相同的参数固定下来

// 正常正则验证字符串reg.test(txt)

//函数封装后
function check(reg,txt){
  return reg.test(txt);
}
//即使是相同的正则表达式,也需要重新传递一次
console.log(check(/\d+/,'test1'))  //true
console.log(check(/\d+/,'testt')) //false

//柯里化(currying)后
function checkCurrying(reg){
  return function (txt){
    return reg.test(txt);
  }
}
var hasNumber = checkCurring(/\d+/);
console.log(hasNumber('test1'));
console.log(hasNumber('testt'));

可以看出当将check函数柯里化后可以固定同一正则表达式这一参数,得到一个只需要接收需要检测的字符串的函数。达到了参数复用的目的。

提前确认

var on = function(element,event,handler){
  if(document.addEventListener){
    if(element && event && handler){
      element.addEventListener(event,handler,false);
    }
  }else{
    if(element && event && handler){
      element.attachEvent('on' + event,handler)
    }
  }
}
on(div,'click',function(){})

var onCurrying = (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);
      }
    }
  }
})()
on(div,'click',function(){})

我们在做项目的过程中,封装DOM的操作可以说再正常不过,上面第一种写法也是比较常见,但是我们看看第二种写法,它相对于第一种写法就是自执行然后返回一个新的函数,这样就提前确定了会走哪一个方法,避免每次都进行判断。

封装通用柯里化函数

接下来我们来封装一个通用的柯里化函数。

function currying(){
  var fn = arguments[0];
  var args = [].slice.call(arguments,1);
  if(fn.length === args.length){
    return fn.apply(this,args);
  }else{
    function _currying(){
      args.push(...arguments);
      if(fn.length === args.length){
        return fn.apply(this,args);
      }else{
        return _currying;
      }
    }
    return _currying;
  }
} 

总而言之,函数柯里化就是将function(Arg1,Arg2,...,Argn)变成function(Arg1)(Arg2)...(Argn)或者function(Arg1,Arg2,...,Argk)(Argk+1)(Argn)

你可能感兴趣的:(javascript)