高阶函数是至少满足下列条件之一的函数
- 函数可以作为参数被传递
- 函数可以作为返回值输出
(js这么好的语言中的函数当然满足 ^^)_
函数作为参数传递
把函数当作参数传递,可以抽离出一部分容易变化的业务逻辑,把这部分业务逻辑放在函数中,可以分离业务代码中变与不变的部分。
- 回调函数,ajax异步,callback
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(面向切面编程),把一些跟核心业务逻辑模块无关的功能抽离出来(通常包括日志统计,安全控制,异常处理等)
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() {
c 大专栏 高阶函数onsole.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延迟一段时间执行,如果这次延迟执行还没完成,则忽略接下来调用该函数的请求。
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);