2020前端面试复习-js部分-函数的防抖和节流

112 阅读2分钟

防抖:防止老年帕金森,对于频繁触发某个操作,我们只识别一次(只触发一次)

  1. @params
    1. func[function]:最后要触发执行的函数
    2. wait[number]:设定频繁的界限
    3. immediate[boolean]:默认多次操作,识别最后一次,如果值为true,识别第一次
  2. @return
    1. 可以被调用执行的函数
//主体思路:在当前点击完成后,我们等wait这么长的时间,看是否还会触发第二次,如果没有触发第二次,属于非频繁操作,我们直接执行想要执行的函数func;如果触发了第二次,则以前的不算了,从当前这次再开始等待
function debounce(func,wait=300,immediate = false) {
    let timer = null;
    return function annoymous(...params) {
        let now = immediate && !timer;
        //每次点击都把之前设置的定时器清除
        clearTimeout(timer);
        //重新设置定时器监听wait时间内是否触发第二次
        //this->当前元素
        timer = setTimeout(()=>{
            //手动让其回归到初始状态
            timer = null;
            //wait这么久的等待中,没有触发第二次
            !immediate ? func.call(this,...params):null;
        },wait);
        //如果当前是立即执行
        now ? func.call(this,...params) :null
    }
}

节流:在一段频繁操作中,可以触发多次,但是触发的频率是由自己指定的

  1. @params
    1. func[function]:最后要触发执行的函数
    2. wait[number]:触发的频率
  2. @return
    1. 可以被调用执行的函数
function throttle(func,wait=300){
    let timer = null,
        previous = 0;//记录上一次操作时间
    return function annoymous(){
        let now = new Date(),
            remaining=wait - (now - previous);//记录还差多久达到我们一次触发的频率
        if(remaining<=0){
            timer = null;
            //两次操作的间隔已经超过wait了
            window.clearTimeout(timer)
            previous = now;
            func.call(this,...parems)
        } else if(!timer) {
            //两次操作时间的间隔不符合触发频率
            timer = setTimeout(()=>{
                timer = null;
                previous = new Date();
                func.call(this,...params)
            },remaining)
        }
    }
}
function handle(){
    console.log('ok)
}
window.onscroll = handle//每一次滚动过程中,浏览器有最快反应时间(5-6ms 13-17ms),只要反应过来就会触发执行一次函数,此时触发频率5ms左右
window.onscroll = throttle(handle)//控制频率为3000ms左右
window.onscroll = function annoymous()//每隔5ms触发一次匿名函数控制频率为3000ms左右,我们可以在匿名函数中控制执行handle的频率