防抖,就是延迟一段时间执行函数,如果在这段时间内又触发这个函数,则延迟重新计算
节流,函数需要隔一段时间才能触发,避免高频触发函数,造成性能损失
防抖节流关键点在于,闭包。
function debounce(fn, delay, maxDelay = null) {
let timer = null;
let nowDate = new Date().getTime();
return function () {
let context = this, arg = arguments;
clearTimeout(timer);
// 节流的体现
if (maxDelay && (new Date().getTime() - nowDate >= maxDelay)) {
fn.apply(context, args);
nowDate = new Date().getTime();
} else {
// 防抖的体现
timer = setTimeout(() => {
fn.apply(context, args);
}, delay)
}
}
}
window.addEventListener('resize', debounce(() => console.log(123), 500, 1000));
debounce
函数里面返回了一个函数,里面的那个函数引用了外部变量 timer
和 nowDate
,这两个变量会在闭包内保持住,因此能延迟触发以及防止频繁触发目的函数。
这样写法,待节流函数超时触发的时候,有可能会导致 fn
的 this
指向错误(当然现在执行的都是属于window的函数,所以没问题,假如,防抖节流函数是执行了一个对象的方法,那么 this
未必是指向这个对象的),因此,最好其实是用 call
,或 apply
来调用。