《JavaScript设计模式与开发》笔记 6.高阶函数
Posted SmarTom
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《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();
流程图
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.高阶函数的主要内容,如果未能解决你的问题,请参考以下文章
javascript设计模式与开发实践阅读笔记(10)—— 组合模式
JavaScript设计模式与开发实践---读书笔记 策略模式
《JavaScript设计模式与开发》笔记 1.面向对象的JavaScript