zoukankan      html  css  js  c++  java
  • 《javascript设计模式与开放实践》学习(三)高阶函数的应用

    一、AOP(面向切面编程)

     Function.prototype.before=function (beforefn) {
            var _self=this;//保持原函数的引用
            return function () {//返回包含原函数和新函数的“代理”函数
                beforefn.apply(this,arguments);//执行新函数,修正this
                return _self.apply(this,arguments);//执行原函数
            }
        }
    
        Function.prototype.after=function (afterfn) {
            var _self=this;
            return function () {
                var ret=_self.apply(this,arguments);
                afterfn.apply(this,arguments);
                return ret;
            }
        }
        var func=function () {
            console.log(2);
        }
        func=func.before(function () {
            console.log(1);
        }).after(function () {
            console.log(3)
        });
    
        func();

    二、currying 函数柯里化

    currying又称部分求值。过程中不进行求值进行数值的保持,在最后一步进行求值。

    如:

     var curring=function (fn) {
            var args=[];
            return function () {
                if(arguments.length==0){
                    return fn.apply(this,args);
                }else{
                    [].push.apply(args,arguments);
                    return arguments.callee //返回正被执行的 Function 对象
                }
            }
        }
        var cost=(function () {
            var money=0;
            return function () {
                for(var i=0,l=arguments.length;i<l;i++){
                    money+=arguments[i];
                }
                return money;
            }
        })();
        var cost=curring(cost);//转换成curring函数
        cost(100);
        cost(200);
        cost(300);
        console.log(cost())

    输出结果600,在前3个函数调用的时候把值保持进数组,在最后一步进行数组求和。

    三、uncurring

    一个对象借用领另一个对象的方法或属性

    将Array.prototype.push uncurring化

    Function.prototype.uncurrying=function () {
            var self=this;
            return function () {
                var obj=Array.prototype.shift.call(arguments);//取出arguments第一个值,并将第一个值从arguments中移除
                return self.apply(obj,arguments);
            };
        };
    
        var push=Array.prototype.push.uncurrying();
        (function () {
            push(arguments,4);
            console.log(arguments);//输出[1,2,3,4]
        })(1,2,3)

    以此类推,其他Array的方法也可以uncurring

    Function.prototype.uncurrying=function () {
            var self=this;
            return function () {
                var obj=Array.prototype.shift.call(arguments);//取出arguments第一个值,并将第一个值从arguments中移除
                return self.apply(obj,arguments);
            };
        };
        for(var i=0,fn,ary=['push','shift','forEach'];fn=ary[i++];){
            Array[fn]=Array.prototype[fn].uncurrying();
        };
        var obj={
            "length":3,
            "0":1,
            "1":2,
            "2":3
        };
        Array.push(obj,4);
        console.log(obj.length);//输出4
        var fist=Array.shift(obj);
        console.log(fist);//输出1
        console.log(obj);//输出{0:2.1:3,2:4,length:3}
    
        Array.forEach(obj,function (i,n) {
            console.log(n);//分别输出0,1,2
        })

    四、函数节流

    解决频繁调用问题

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

    五、分时函数

    防止一次性加载过多,进行分时调用。

     var timeChunk=function (ary,fn,count) {
            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 () {
                t=setInterval(function () {
                    if(ary.length===0){//如果全部节点都已经创建好
                        return clearInterval(t);
                    }
                    start();
                },200)//分批执行的时间间隔
            }
        }
        var ary=[];
        for(var i=1;i<=1000;i++){
            ary.push(i);//假设ary装载了1000个好友
        }
        var renderFriendList=timeChunk(ary,function (n) {
            var div=document.createElement('div');
            div.innerHTML=n;
            document.body.appendChild(div);
        },8);
        renderFriendList();

    六、惰性加载函数

    第一次进入分支后重写函数,第二次不在进行分支判断

     var addEvent=function (elem,type,handler) {
            if(window.addEventListener){//非IE
                addEvent=function (elem,type,handler) {
                    elem.addEventListener(type,handler,false);
                }
            }
            else if(window.attachEvent){//非W3C标准,只支持IE
                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);
        });
  • 相关阅读:
    26. Remove Duplicates from Sorted Array(js)
    25. Reverse Nodes in k-Group(js)
    24. Swap Nodes in Pairs(js)
    23. Merge k Sorted Lists(js)
    22. Generate Parentheses(js)
    21. Merge Two Sorted Lists(js)
    20. Valid Parentheses(js)
    19. Remove Nth Node From End of List(js)
    18. 4Sum(js)
    17. Letter Combinations of a Phone Number(js)
  • 原文地址:https://www.cnblogs.com/GallopingSnail/p/5879120.html
Copyright © 2011-2022 走看看