zoukankan      html  css  js  c++  java
  • 《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.高级函数的实现AOP
    
    Function.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();

    流程图 image

    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>
  • 相关阅读:
    [HEOI2016/TJOI2016]树
    [BJOI2018]求和
    洛谷P5002 专心OI
    [GDOI2014]采集资源
    小凯的数字
    APP微信支付
    java对接支付宝支付
    layui 视频上传本地(项目)
    mybatis Generator生成代码及使用方式
    Java IO流学习总结
  • 原文地址:https://www.cnblogs.com/subtract/p/7139902.html
Copyright © 2011-2022 走看看