这是我参与「第五届青训营 」笔记创作活动的第 4 天
前言
高阶函数HOF(Higher Order Function)是JS中进阶部分的重要内容之一,高阶函数会接收一个或者多个函数作为参数,并输出一个函数作为返回值。高阶函数常被应用于当代web开发中,例如节流函数或者定时输出函数,在JS的内置方法中也有高阶函数的存在,例如reduce、sort和map等等。本篇文章将会介绍一些常见的高阶函数
高阶函数示例
在本章将会为大家介绍几个高阶函数:①节流函数、②定时输出函数、③只执行一次函数
1. 节流函数
在前端开发中,我们通常会定义一个元素的事件,例如click事件或者mouseup事件等等,当我们短时间内一直触发这些事件,但实际上一些操作我们不希望记录触发太多次事件,触发太多次事件会浪费计算机的资源导致运行速度减慢,于是我们引入了节流函数的概念。
我们借助定时器作为辅助,传入的第一个参数为需要节流的事件函数,第二个参数为触发事件的时间间隔。
/**
* 函数节流
* 500ms内多次点击只会算一次
* @param {Function} fn 需要进行节流的函数
* @param {Number} cycle 每次执行指定函数的间隔时间,默认值为500ms
* @return {Function} fn 指定的函数
*/
function throttle(fn, cycle = 500) {
let _timer;
return function (...args) {
if (_timer == null) {
fn.apply(this, args);
_timer = setTimeout(() => {
_timer = null;
}, cycle);
}
};
}
根据上方的代码分析,我们的节流函数控制流量主要通过以下几个步骤:
- 定义一个变量_timer代表定时器是否存在
- 进行判断此时的定时器是否存在
- 若存在,说明上一个函数还未执行完成
- 若不存在,则重新创建一个定时器
2. 定时输出函数
定时输出表示当我们执行JS代码的时候,计算机的运算速度非常快,会在很短的时间内执行并输出我们的执行结果,如果我们需要控制台或者是前端页面不“那么快”的输出,可以引入定时输出函数。
与节流函数一致,需要传入两个参数,第一个是执行的函数,第二个是间隔的时间
/**
* 间隔执行函数
* @param {Function} fn
* @param {number} time
* @returns {Function} fn
*/
function consumer(fn, time = 1000) {
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);
}
}
}
如果已经理解了上一节的节流函数的执行步骤,其实定时输出函数也是同样的原理,执行步骤是:
- 定义tasks为任务列表,timer作为辅助变量帮助我们判断定时器是否存在
- 将需要执行的任务丢到任务执行列表中
- 判断定时器是否存在,如果存在则等待
- 如果定时器不存在说明上一个任务已经执行完毕,我们执行继续执行下一个函数
只执行一次函数
其实了解了以上两个函数后,对应执行一次的函数其实大家应该也有了自己的想法。顾名思义,该函数就是为了控制事件的执行次数,当多次触发事件的时候,只执行一次事件,后续多次触发事件无效。
/**
* 执行一次函数
* @param {Funcion} fn
* @return {Function} fn
*/
function once(fn) {
return function(...args) {
if(fn){
const ret = fn.apply(this, args)
fn = null
return ret
}
}
}
这一个函数的执行的原理其实一目了然,步骤就是传入一个函数,如果没执行过就执行该函数,之后把该函数赋予null值,这样后续再传入同一个函数的时候就不会继续执行这个函数了。
总结
在青训营中月影老师还为我们介绍了更多的高阶函数及其使用方法,但无论是JS或者是HTML部分,都有更多的更深的内容等待我们大家去探索,高阶函数作为JS中进阶部分的内容理解起来可能会有一些困难,但是了解其原理后实现起来并不是难事,相信不久后的大家都会在顶峰相见。