首页 > 代码库 > 《javascript设计模式与开放实践》学习(三)高阶函数的应用
《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); });
《javascript设计模式与开放实践》学习(三)高阶函数的应用
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。