0%

高阶函数


高阶函数是至少满足下列条件之一的函数

  • 函数可以作为参数被传递

  • 函数可以作为返回值输出
    (js这么好的语言中的函数当然满足 ^^)_

函数作为参数传递

把函数当作参数传递,可以抽离出一部分容易变化的业务逻辑,把这部分业务逻辑放在函数中,可以分离业务代码中变与不变的部分。

  • 回调函数,ajax异步,callback
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); //执行新函数,修正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();

以上代码我们把打印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);
我知道是不会有人点的,但万一有人想不开呢?