防抖与节流(闭包在其中的作用)

84 阅读2分钟

在面试中常见手写之防抖节流函数

防抖

防抖:在触发一次函数后的规定时间内,如果没有再次触发,才执行。 比如电梯进门,一直进就不关闭。只执行最后一次

节流

节流:一段时间内连续触发,在规定时间内只执行一次,控制高频事件执行次数。比如拖动滚动条,不用节流就会触发非常多次(技能cd)

重点

函数中的this指向问题
在settimeout中调用fun,fun的上下文会指向window,显然不正确。而且fun传入的参数也没有 所以要使用args记录fun传入时的参数 this则是使用箭头函数记录return function(){}的作用域,function(){}不使用箭头函数,this指向为和window

手写防抖函数

<body>
    <button id="btn">按钮,一直按就不会加,停止然后等待1秒就会得出结果</button>   <!-- 按钮实现 -->

    <script>
        function debounce(fun,wait){
            let args = [...arguments]
            let timeout
      
            return function(){ //这里不能使用箭头函数,
                clearTimeout(timeout)
                timeout = setTimeout(() => {
                    fun.apply(this,args)
                }, wait);
            }
        }

    let count=0        
    let btn=document.getElementById("btn")  
    function add(e){
        count++    
      console.log(count)
    }
    btn.addEventListener('click',debounce(add,1000))    
   </script>
</body>

手写节流函数

时间戳版本

function throttle(fun,wait){ //节流函数时间cuo版本

            let args = [...arguments]

            let pretime = 0

            return function(){

                let now = new Date().getTime()

                if( now - pretime > wait ){//如果现在减去过去的时间大与等待cd,就执行

                    fun.apply(this,args)

                    pretime = now

                }

            }

        }

还有计时器方法

function myThrottle(fn, delay) {
    let timer = null;
    return function () {
        // 这儿是重点  如果时间没到  那么 timer 就不为 null  就会返回  不会往下执行!!!
        if (timer) {
            return
        };
        timer = setTimeout(() => {
            // 时间到了  timer  被设置为null  就走到这儿来了 就会执行 
            fn.apply(this, arguments)
            timer = null
        }, delay);
    }
};
// 综合上面两步 就实现了 英雄 技能cd  一样的节流

防抖函数中闭包起了什么作用?

防抖是闭包的重要应用例子之一,主要是timeout变量的保留上 在防抖函数中,闭包用来保存定时器的timeout(id),在每次函数被调用后,通过闭包中的定时器ID可以清除之前的定时器,从而避免函数被频繁触发。这样就能确保在一定的时间间隔内只执行一次函数,实现了防抖的效果。