首页 > 代码库 > 《JavaScript设计模式与开发》笔记 6.高阶函数

《JavaScript设计模式与开发》笔记 6.高阶函数

  •  1.函数作为参数传递
    • 1.回调函数
    • 2.Array.prototype.sort
  •  2.函数作为返回值输出
    • 1.判断数据的类型
  •  3.高级函数的实现AOP
  •  4.高阶函数的其他应用
    • 1.currying 函数柯里化
    • 2.uncurring
    • 3.函数节流
    • 4.分时函数
    • 5.惰性加载函数

1.函数作为参数传递

1.回调函数

最经常用的或许就是异步Ajax了

var getUserInfo = function(userId,callback){    $.ajax("http://xxx.com/getUserInfo?"+userId,function(data){       callback(data);     });}getUserInfo(14157,function(data){    alert(data.userName);});

 

2.Array.prorotype.sort

var array = [1,2,4];array.sort(function(a,b){    return b-a;});console.log(array);

 


2.函数作为返回值输出

1.判断数据的类型

场景

var isString = function(obj){    return Object.prototype.toString.call(obj) == ‘[object string]‘;}var isArray = function(obj){    return Object.prototype.toString.call(obj) ==‘[object Array]‘;}var isNumber = function(obj){    return Object.prototype.toString.call(obj) == ‘[Object Number]‘};以上代码可写成:var isType = function(type){    return function(obj){   //函数作为返回值进行返回        return Object.prototype.toString.call(obj) === ‘[object ‘+type+‘]‘;    }}var isString = isType(‘String‘);var isArray = isType(‘Array‘);var isNumber = isType(‘Number‘);console.log(isString([1,2,3,4]));3.高级函数的实现AOPFunction.prototype.before=function(beforefn){    var _self = this;           //这里的this实际上是func的this    return function(){        //这个this是before 的this        beforefn.apply(this,arguments);         //这个是函数        return _self.apply(this,arguments);    //func函数    }}Function.prototype.after=function(afterfn){    var _self = this;           //这里的this实际上是func的this    return function(){        var ret = _self.apply(this,arguments);  //func函数  实际上func可以包含before函数函数        //这个this是after 的this        afterfn.apply(this,arguments);         //这个是函数        return ret;    }}var func = function(){    console.log(‘2‘);}var asdf = func.before(function(){    console.log(‘1‘);}).after(function(){    console.log(‘3‘);});asdf();

 

流程图 技术分享

3.高阶函数其他应用

1.函数柯里化 currying函数

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

var currying = function(fn){    var args = [];    return function(){        if(arguments.length == 0){            var Mynameisbalabala;            return fn.apply(this,args); //不要被这个this迷惑,实际是将argus传递给cost进行计算            //return fn.apply(Mynameisbalabala,args);        }else{            [].push.apply(args,arguments);            return arguments.callee;    //返回该函数        }    }};var ASF2FASD = (function(){    var money = 0;    return function(){        for(var i=0;i<arguments.length;i++){            money +=arguments[i];        }        return money;    }})();var ASDFA = currying(ASF2FASD);console.log(ASDFA(100).toString());/* ASDF(100) 返回 ==(return fn.apply(this,args))function (){        if(arguments.length == 0){            var Mynameisbalaba;            return fn.apply(this,args); //不要被这个this迷惑,实际是将argus传递给cost进行计算            //return fn.apply(Mynameisbalaba,args);        }else{            [].push.apply(args,arguments);            return arguments.callee;    //返回该函数        }    }*/ASDFA(100);//ASDFA(100);//ASDFA(300);//console.log(ASDFA());   //600

 

2.uncurrying函数

在JavaScript中,当我们调用对象的某个方法时,其实不用关心该对象原本是否设计为拥有这个方法,这是动态类型语言的特点,也是常说的鸭子类型的意思。


我们常用call和apply可以把任意对向当做this传入某个方法,这样一来,方法中用到this的地方就不在局限与原来规定的对象,而是加以泛化并得到更广的适用性。那么有没有把泛化this的过程提取出来呢....

仔细看一下代码还是很简单的不注解了.....

Function.prototype.uncurrying = function(){    var self = this;//此时是Array.prototype.push    return function() {        var obj = Array.prototype.shift.call(arguments);        //obj是{        //‘length‘:1,        //‘0‘:1        //}        //arguments 对象的第一个元素被截取        return self.apply(obj,arguments);        //相当于 Array.prototype.push.apply(obj,2);    }}var push = Array.prototype.push.uncurrying();var obj = {    "length":1,    "0":1}push(obj,2);console.log(obj);

 

除了这样方法下面代码也是uncurrying的另一个实现方式:【】

Function.prototype.uncurrying = function(){    var self = this;    return function(){        // Function.prototype.call  { ‘0‘: 1, length: 1 }        return Function.prototype.call.apply(self,arguments);       //self =>asdfasdfasdfasdf对象  这里的this的话应该是push    }}var push = Array.prototype.push.uncurrying();var asdfasdfasdfasdf = {    "length":1,    "0":1}push(asdfasdfasdfasdf,2);console.log(asdfasdfasdfasdf);

 

3.函数节流

函数调用频率过高,非常消耗性能的情况下使用函数节流比如监视窗口浏览器大小,比如监视鼠标的移动效果

实现节流:

var throttle = function (fn,interval){    var _self = fn, //保存需要执行的函数引用        timer,      //定时器        firstTime = true;   //是否是第一次执行调用            return function(){        var args =arguments,        __me = this;  //要执行的函数        if(firstTime){              //如果是第一次调用,不需要延迟执行            _self.apply(__me,args);            return firstTime = false;        }        if(timer){      //如果定时器还在,说明前一次延迟执行还没有完成            return false;        }        timer = setTimeout(function(){            clearTimeout(timer);            timer = null;            _self.apply(__me,args);        },interval || 500);    }}window.onresize = throttle(function(){    console.log(‘1‘);},1000);

 

4.分时函数

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body></body><script>    var timeout = function(ary,fn,count){        console.log(‘5‘);        var obj,              t;        var len = ary.length;        var start = function(){            for(var i=0;i<Math.min(count || 1,ary.length);i++){                var obj = ary.shift();                fn(obj);            }        };        return function(){            console.log(‘1‘);            t = setInterval(function(){                if(ary.length === 0){                    return clearInterval(t);                }                start();            },1000);        };    };    var ary = [];    for(var i=1;i<=1000;i++){        ary.push(i);    };    var renderFriendList = timeout(ary,function(n){        var div = document.createElement("div");        div.innerHTML = n;        document.body.appendChild(div);    },8);    renderFriendList();</script></html>

 

5.惰性加载函数

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body><div id="div1">点击我绑定事件</div></body><script>    var addEvent = function(elem,type,handler){        if(window.addEventListener){            addEvent = function(elem,type,handler){                elem.addEventListener(type,handler,false);            }        }else if(window.attachEvent){            addEvent = function(elem,type,handler){                elem.attachEvent(‘on‘+type,handler);            }        }        addEvent(elem,type,handler);    }    var div = document.getElementById(‘div1‘);    addEvent(div,‘click‘,function(){        alert(‘1‘);    })    addEvent(div,‘click‘,function(){        alert(‘2‘);    })</script></html>

 

《JavaScript设计模式与开发》笔记 6.高阶函数