防抖鸠天,就是延遲一段時(shí)間執(zhí)行函數(shù)讼育,如果在這段時(shí)間內(nèi)又觸發(fā)這個(gè)函數(shù),則延遲重新計(jì)算
節(jié)流稠集,函數(shù)需要隔一段時(shí)間才能觸發(fā)奶段,避免高頻觸發(fā)函數(shù),造成性能損失
防抖節(jié)流關(guān)鍵點(diǎn)在于剥纷,閉包痹籍。
function debounce(fn, delay, maxDelay = null) {
let timer = null;
let nowDate = new Date().getTime();
return function () {
let context = this, arg = arguments;
clearTimeout(timer);
// 節(jié)流的體現(xiàn)
if (maxDelay && (new Date().getTime() - nowDate >= maxDelay)) {
fn.apply(context, args);
nowDate = new Date().getTime();
} else {
// 防抖的體現(xiàn)
timer = setTimeout(() => {
fn.apply(context, args);
}, delay)
}
}
}
window.addEventListener('resize', debounce(() => console.log(123), 500, 1000));
debounce
函數(shù)里面返回了一個(gè)函數(shù),里面的那個(gè)函數(shù)引用了外部變量 timer
和 nowDate
晦鞋,這兩個(gè)變量會(huì)在閉包內(nèi)保持住蹲缠,因此能延遲觸發(fā)以及防止頻繁觸發(fā)目的函數(shù)棺克。
這樣寫法,待節(jié)流函數(shù)超時(shí)觸發(fā)的時(shí)候线定,有可能會(huì)導(dǎo)致 fn
的 this
指向錯(cuò)誤(當(dāng)然現(xiàn)在執(zhí)行的都是屬于window的函數(shù)娜谊,所以沒問題,假如斤讥,防抖節(jié)流函數(shù)是執(zhí)行了一個(gè)對象的方法纱皆,那么 this
未必是指向這個(gè)對象的),因此芭商,最好其實(shí)是用 call
派草,或 apply
來調(diào)用。