目录
序言:
防抖(debounce)
节流(throttle)
代码示例
附录:
关于节流/防抖函数中 context(this) 的指向解析:
防抖函数中的 this 指向
节流函数中的 this 指向
我们在平时开发的时候,会有很多场景会频繁触发事件,比如说搜索框实时发请求,onmousemove, resize, onscroll等等,有些时候,我们并不能或者不想频繁触发事件,咋办呢?这时候就应该用到函数防抖和函数节流了!
防抖(debounce)是指在一定时间内,只执行最后一次触发的事件。它适用于那些在连续触发事件的过程中,只关心最后一次触发的结果的情况。
例如,当用户连续输入搜索关键字时,我们可以使用防抖来减少网络请求的次数。在用户停止输入一段时间后,才发送网络请求进行搜索。
下面是一个简单的 JavaScript 实现防抖函数的例子:
function debounce(func, delay) {
let timer;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
这个 debounce 函数接受两个参数:func 是要执行的函数,delay 是延迟的时间。在每次触发事件时,它会清除之前设置的定时器,并重新设置一个新的定时器。如果在延迟时间内再次触发事件,定时器会被清除并重新设置。只有在延迟时间结束后没有再次触发事件,才会执行函数。
节流(throttle)是指在一定时间内,固定执行事件的频率。它适用于那些在连续触发事件的过程中,需要保持一定的执行频率的情况。
例如,当用户持续滚动页面时,我们可以使用节流来限制处理滚动事件的频率,以避免过多的计算和渲染。
下面是一个简单的 JavaScript 实现节流函数的例子:
function throttle(func, delay) {
let timer;
return function() {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, arguments);
timer = null;
}, delay);
}
};
}
这个 throttle 函数接受两个参数:func 是要执行的函数,delay 是延迟的时间。在每次触发事件时,它会检查是否存在定时器,如果不存在则设置一个新的定时器,并在延迟时间结束后执行函数。这样可以保证在延迟时间内只执行一次函数。
总结起来,防抖和节流都是用于优化性能和控制事件触发频率的技术。防抖适用于只关心最后一次触发结果的情况,而节流适用于需要保持一定执行频率的情况。
防抖和节流示例
在防抖和节流函数中,this 的指向非常重要。下面分别解析一下:
在防抖函数中,如果不加以处理,this 会指向当前调用防抖函数的对象(例如 window 对象)。因此,我们需要使用 Function.prototype.apply() 或 Function.prototype.call() 方法来明确指定 this 的值。
例如,以下代码中的 handleInput 函数在执行时,this 会指向 input 元素本身:
这里的 this 表示当前的 input 元素。通过 call() 方法将 this 明确指定为 debouncedHandleInput 函数中的 this。
在节流函数中,this 的指向与防抖函数略有不同。在节流函数中,this 通常应该指向事件的目标元素(例如 button 元素),而不是当前调用节流函数的对象(例如 window 对象)。
例如,以下代码中的 handleClick 函数在执行时,this 会指向 button 元素本身:
这里的 this 表示当前的 button 元素。在 throttledHandleClick 函数中,可以使用 this 来获取目标元素的属性、修改样式等操作。
需要注意的是,在使用箭头函数定义防抖和节流函数时,this 的指向不会改变,仍然指向外层作用域的 this。
综上所述,防抖和节流函数中的 this 指向应该根据实际情况进行明确指定。