什么是防抖函数
JavaScript中由于函数调用太过频繁而预先设置一个时间间隔,如果超过这个间隔函数没有被调用,才真正开始执行,否则不执行继续等待之后的调用的设计,被称为函数防抖(debounce)。
函数防抖的简单实现:
const debounce = ( func, wait=500 ) => {
let timer;
return function(...param){
clearTimeout(timer)
timer = setTimeout( ()=>{
func.call(this,...param) //参数写法解释在下面
},wait )
}
}
//当屏幕尺寸变化时
window.onresize = debounce(e => console.log('hello world'), 2000);
debounce函数接收2个参数,第1个是需要防抖的目标函数,第2个是防抖等待的时间wait(默认值100ms)。debounce是一个闭包,它返回的函数有一个私有变量timeout,当函数每次触发时,timeout都被清除一次,然后重新设置一个新的定时器,用于执行防抖目标函数,定时器等待的时间是wait毫秒。
接着测试window.onresize事件,尝试改变浏览器窗口的大小,会发现无论改变窗口的速度多快,只要500ms内又重新改变了窗口,之前触发的逻辑都不会被执行。
window.onresize = debounce(e => console.log('hello world'), 500);
除此之外,还可以测试目标函数执行的上下文(this和函数参数),这里可以尝试在目标函数中输出this和e试试,会发现和正常情况下(不适用debounce绑定目标函数)一样,this和函数参数都能被正常使用。
这是因为debounce中返回的是一般的函数声明而没有用箭头函数,而里面的setTimeout却是箭头函数,这样就保证了防抖目标函数被调用时的上下文和正常情况下一样。
什么是节流函数
函数节流就是当目标函数被连续频繁调用时,目标函数并不会每次调用都被执行,而是间隔一个设定好的时间再执行。
函数节流的简单实现:
const throttle = (func, wait = 50) => {
var lastCall = Date.now();
return function(...args) {
const now = Date.now();
if (now - lastCall > wait) {
func.call(this, ...args); //参数写法解释在下面
lastCall = now;
}
};
};
//当鼠标经过时
document.body.onmousemove = throttle(e => {
console.log('hello world');
}, 200);
这里创建一个函数节流的简单实现,每次调用都记录一下当前时间,看看是否和上次调用的时间差是否大于指定的时间差,如果大于则调用目标函数,并且记录当前时间为新的上一次调用时间。
这是同一类问题的两种解决方法,以备后查!