惰性函数和函数柯里化

惰性函数

惰性载入表示函数执行的分支只会在函数第一次调用的时候执行,在第一次调用过程中,该函数会被覆盖为另一个按照合适方式执行的函数,这样任何对原函数的调用就不用再经过执行的分支了。
例如:为了兼容各浏览器,对事件监听的支持:

function addEvent (type, element, fun) {
    if (element.addEventListener) {
        element.addEventListener(type, fun, false);
    }
    else if(element.attachEvent){
        element.attachEvent('on' + type, fun);
    }
    else{
        element['on' + type] = fun;
    }
}

上面是注册函数缉拿提供的个浏览器兼容函数。由于各浏览器之间的差异,不得不在用的时候做能力检测。显然,单从功能上讲,已经做到了兼容各浏览器。但是每次监听,都会做一次能力检测,这就没必要了,真正的应用中,这显然是多余的,对同一个应用环境中,只需做一次检测即可。
于是做如下改变:

 


    
    


  

可以看出,第一次调用addEvent会对浏览器做能力检测,然后重写了addEvent。下次函数被重写,不会再做能力检测了。
类似的经典例子还有:XMLHttpRequest

function createXHR() {
      var xhr;
      if(typeof XMLHttpRequest != 'undefined') {
          xhr = new XMLHttpRequest();
        createXHR = function() {
             return new XMLHttpRequest();
         }
     }else {
        try {
            xhr = new ActiveXObject("Msxml2.XMLHTTP");
            createXHR = function() {
                 return new ActiveXObject("Msxml2.XMLHTTP");
             }
         }catch(e) {
            try {
                 xhr = new ActiveXObject("Microsoft.XMLHTTP");
                 createXHR = function() {
                     return new ActiveXObject("Microsoft.XMLHTTP"); 
                 }
            }catch(e) {
                 createXHR = function () {
                     return null;
                 }
            }
       }
     }
    return xhr 
 }

代码中,我们让函数在第一次运行之后,则判断除了浏览器的环境,就被重新赋值了。赋值后的函数是直接return对应的方法。所以这个函数需要第二次调用的时候才真正的被调用。
正式因为它第二次调用的饿时候,没有去走第一次调用那样复杂的判断的路,才显得“懒惰”。因此我们叫惰性函数。

惰性函数应用场景

1、应用频繁,如果只用一次,是体现不出来它的优点的,用的次数越多,越能体现这种模式的优势所在;
2、固定不变,一次判定,在固定的应用环境中不会发生改变;

函数柯里化

函数柯里化又称部分求值,一个柯里化的函数首先会接受一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。

 var currying = function(fn){
        var args = [];
        return function(){
           if(arguments.length === 0){
             return fn.apply(this,args);
          }else{
            [].push.apply(args,arguments);
            return arguments.callee;
          }
        }
     }
    var cost = (function(){
        var money = 0;
        return function(){
          for(var i = 0 ,l = arguments.length; i

以上代码中,完成了一个currying函数的编写。当调用cost()时,如果明确地带上了一些参数,表示此时并不进行真正的求值计算,而是把这些参数保存下来,此时让cost函数返回另外一个函数。只有以不带参数的而形式执行cost()时,才利用前面保存的所有参数,真正开始进行求值计算。

你可能感兴趣的:(惰性函数和函数柯里化)