高阶函数是至少满足下列条件之一的函数
函数作为参数传递
把函数当作参数传递,可以抽离出一部分容易变化的业务逻辑,把这部分业务逻辑放在函数中,可以分离业务代码中变与不变的部分。
1 2 3 4 5 6 7 8 9 10
| var getUserInfo() = function(userId, callback) { $.ajax('http://xxx.com/getUserInfo?' + userId, function(data) { if (typeof(callback === 'function') { callback(data); } }); } getUserInfo(13157, function(data) { alert(data.user); })
|
高阶函数实现AOP
AOP(面向切面编程),把一些跟核心业务逻辑模块无关的功能抽离出来(通常包括日志统计,安全控制,异常处理等)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| Function.prototype.before = function(beforefn) { var __self = this; return function() { beforefn.apply(this, arguments); 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();
|
以上代码我们把打印1和打印3的函数通过AOP的方式动态植入func函数,于是执行时候顺利返回1,2,3
函数节流
js函数大多是用户触发,大多不会遇到跟性能相关的问题,但是少数情况触发不被用户控制的。
例如:
-
window.onresize事件
-
mousemove事件
-
上传进度
以上函数触发频率太高,比如我们对onresize事件绑定了打印事件,当拖动窗口时,可能会一秒打印十次,这太累了,因此要采取一点措施(聪明的机智的你一定想到了setTimeout)
主要实现原理:当即将被执行的函数用setTimeout延迟一段时间执行,如果这次延迟执行还没完成,则忽略接下来调用该函数的请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| 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); }, 500);
|