JavaScript之节流与防抖

我的博客原文地址git

背景

咱们在开发的过程当中会常常使用如scroll、resize、touchmove等事件,若是正常绑定事件处理函数的话,有可能在很短的时间内屡次连续触发事件,十分影响性能。
所以针对这类事件要进行节流或者防抖处理github

节流

节流的意思是,在规定的时间内只会触发一次函数,如咱们设置函数500ms触发一次,以后你不管你触发了多少次函数,在这个时间内也只会有一次执行效果app

先来看一个例子函数

https://codepen.io/wclimb/pen...性能

咱们看到使用了节流的在1000ms内只触发了一次,而没有使用节流的则频繁触发了调用的函数this

接下来看看代码实现
v1 第一次不触发,不传参实现code

function throttle(fn,interval){
    var timer;
    return function(){
        if(timer){
            return
        }
        timer = setTimeout(() => {
            clearTimeout(timer)
            timer = null
            fn()
        }, interval || 1000);
    }   
}

效果是实现了,可是我在尝试在执行函数里console.log(this),结果发现this指向的是window,并且还发现咱们不能传递参数,下面就来改进一下事件

v2 第一次触发函数,接收参数ip

function throttle(fn,interval){
    var timer,
        isFirst = true;
    return function(){
        var args = arguments,
            that = this;
        if(isFirst){
            fn.apply(that,args)
            return isFirst = false
        }
        if(timer){
            return
        }
        timer = setTimeout(() => {
            clearTimeout(timer)
            timer = null
            fn.apply(that,args)
        }, interval || 1000);
    }   
}

防抖

防抖的意思是不管你触发多少次函数,只会触发最后一次函数。最经常使用的就是在表单提交的时候,用户可能会一段时间内点击不少次,这个时候能够增长防抖处理,咱们只须要最后一次触发的事件开发

先来看一个例子

https://codepen.io/wclimb/pen...

咱们看到使用了防抖的方框,不管你在里面触发了多少次函数,都只会触发最后的那一次函数,而没有使用防抖的则频繁触发了调用的函数

v1 第一次不触发函数

function debounce(fn,interval){
    var timer;
    return function(){
        var args = arguments,
            that = this;
        if(timer){
            clearTimeout(timer)
            timer = null
        }
        timer = setTimeout(() => {
            fn.apply(null,args)
        }, interval || 1000);
    }
}

上面这段代码仍然能够正常执行,可是咱们并无指定他的this

v2 第一次就触发函数

function debounce(fn,interval){
    var timer,
        isFirst  = true,
            can = false;
    return function(){
        var args = arguments,
            that = this;
        if(timer){
            clearTimeout(timer)
            timer = null
        }
        if(isFirst){
            fn.apply(that,args)
            isFirst = false
            setTimeout(() => {
                can = true
            }, interval || 1000);
        }else if(can){
            timer = setTimeout(() => {
                fn.apply(null,args)
            }, interval || 1000);
        }
    }
}

若有雷同,纯属抄我(开玩笑)

若有错误,还望指正,仅供参考

GitHub:wclimb