认识 JS 中的函数防抖
什么是函数防抖?
举个简单的例子,我们为页面注册 mousemove 事件时,我们可以预知的是 mousemove 事件的触发频率十分之高,如果我们在 mousemove 事件中进行了比较费时的操作(比如修改dom的布局),则页面可能会发生卡顿的现象,这种现象我称它为抖动。
函数防抖的原理
JS 中有提供的有两个定时器的功能,一个是 setInterval,另一个是 setTimeout,函数防抖就是利用了 setTimeout 延迟执行的原理进行实现,函数防抖函数我们只需实现一遍,后续即可重复使用
函数防抖的代码实现
/**
* 函数防抖
* @param {function} fn: 要执行的函数
* @param {number} delay: 要延迟的时间,单位为毫秒
*/
function debounce(fn, delay) {
// 1. 返回一个函数
// 2. 因为使用 setTimeout 来实现防抖,
// 要声明一个 timerId 来接收 setTimeout 的返回值
var timerId; // 每次函数执行,都会产生一个新的函数作用域,所以每次调用 debounce 方法 timerId 都是不同的
// 将进行处理防抖的函数返回出去
return function () {
// 3. 处理要传入的参数的问题,因为参数的数量、类型都是不确定的
// 所以不能参数不能按固定的书写方式一个个传入,已知函数中存在一个
// arguments 类数组,里面存放着所有的参数信息
// 又知 使用apply方法会改变this指向,而参数的传入方式是一个数组
// 4. 将类数组转换成真正的数组
var args = Array.prototype.slice.call(arguments);
// 5. 被调用后先清除上一次的定时器,这样上一次的定时器被清除,
// 从而避免事件触发的太频繁而频繁执行我们绑定的不希望频繁被执行的函数
clearTimeout(timerId);
// 6. 重新为timerId 赋值
timerId = setTimeout(function () {
// 7. 使用apply方法将参数已数组的形式传递进去
fn.apply(this, args);
}, delay)
}
}
应用场景
鼠标移动、窗体大小发生改变事件等触发频率过高的事件,当我们不希望它触发的那么频繁的时候,我们使用函数防抖来处理
举个例子,当窗体大小发生改变的时候我们需要在控制台打印一句话。
```javascript
window.onresize = debounce(function () {
console.log('窗体的大小被改变了');
}, 666)
```
> 上面的 onresize 事件绑定的方法,只用当窗体大小停止改变 666 毫秒之后才会在控制台进行打印