这是我参与「第五届青训营 」伴学笔记创作活动的第 5天
前言
上次记录到js的组件封装,这次继续上次的课程内容记录。
高阶函数
以函数作为参数,以函数作为返回值,常用于作为 函数装饰器
常用高阶函数
Once 只执行一次,前文讲过,这里不再阐述
Throttle 节流
为函数添加一个间隔time,每隔time事件调用一次函数,节省其需求,比如某个事件很容易持续的发生(如鼠标移上去就触发),那么他会一直速度特别快的调用这个事件函数,这个时候为其加一个节流函数则可以防止崩溃节约流量。
function throttle(fn, time = 500) {
let timer;
return function(...args) {
if(timer == null) {
fn.apply(this, args);
timer = setTimeout(() => {
timer = null;
}, timer);
}
}
}
btn.onclick = throttle(function(e){
/* 事件处理 */
circle.innerHTML = parseInt(circle.innerHTML)+1;
circle.className = 'fade';
setTimeout(() => circle.className = '', 250);
});
//输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
对原始的函数进行包装,没有timer的话就注册一个timer,500ms后取消,因为在这500ms中这个timer都还存在,所以不会去执行函数(或者说执行空函数),500ms后timer取消了,函数就可以被调用执行了。
Debounce 防抖
在上面的节流中,timer存在期间是不会去执行函数,而防抖是在每次事件一开始的时候清空timer,然后设置timer为dur,当事件调用dur时间并且没有新的事件再次调用时(比如鼠标移动后悬停一段时间),函数就可以被调用执行了。
function debounce(fn, dur) {
dur = dur || 100; // dur若不存在则设置dur为100ms
var timer;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, dur);
}
}
1
2
3
4
5
6
7
8
9
10
Consumer
这是将一个函数变成类似setTimeout这样的异步操作的函数,如调用了很多次某事件,将这些事件丢到一个列表中,按设定好的时间隔一段时间并执行返回其结果。先来看代码:
function consumer(fn, time) {
let tasks = [],
timer;
return function (...args) {
tasks.push(fn.bind(this, ...args));
if(timer == null) {
timer = setInterval(() => {
tasks.shift().call(this);
if(tasks.length <= 0) {
clearInterval(timer);
timer = null;
}
}, time);
}
}
}
btn.onclick = consumer((evt) => {
/*
* 事件处理 如每次调用了很多次某事件,将这些事件丢到
* 一个列表中,按设定好的时间隔一段时间并执行返回其结果。
*/
let t = parseInt(count.innerHTML.slice(1)) + 1;
count.className = 'hit';
let r = t * 7 % 256,
g = t * 17 % 128,
b = t * 31 % 128;
count.style.color = `rgb(${r}, ${g}, ${b})`.trim();
setTimeout(() => {
count.className = 'hide';
}, 500);
}, 800);
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
29
30
31
这里的事件处理实现了点击按钮时执行这个不断显示+count并在500ms后渐隐,而快速点击时,则将这个点击事件存储到是事件列表中每隔800ms执行(不然上一个+count还未消失)。
Iterative
将一个函数,变成可迭代使用的的,这通常用于一个函数要给一组对象执行批量操作的时候。如批量设置颜色,代码如下:
const isIterable = obj => obj != null && typeof obj[Symbol.iterator] === 'function';
function iterative(fn) {
return function(subject, ...rest) {
if(isIterable(subject)) {
const ret = [];
for(let obj of subject) {
ret.push(fn.apply(this, [obj, ...rest]));
}
return ret;
}
return fn.apply(this, [subject, ...rest]);
}
}
const setColor = iterative((el, color) => {
el.style.color = color;
})
const els = document.querySelectorAll('li:nth-child(2n+1)');
setColor(els, 'red');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
总结
这次的记录主要是对课程内容做一个记录,不做特别多的解释了,因为这些网上都有很好的文章了。