JS-详细的防抖和节流

1、防抖和节流

(1)比较

  防抖 节流
概念 一段时间内频繁触发同一事件,只会最后执行一次事件函数 在规定时间内,无论触发多频繁,会且只会执行一次事件函数
实现原理(延时处理) 设置一个计时器,约定在XX毫秒后再触发事件处理,每次触发事件都会重置计时器,直到XX毫秒内无第二次操作  设置一个计时器,约定XX毫秒后执行事件,如果时间到了,就执行函数,并重置计时器
应用场景 搜索框/滚动条的监听事件处理等。如果不做防抖,每输入一个字/滚动屏幕,都会触发事件处理,造成性能浪费 窗口调整,页面滚动,抢购疯狂点击等。防止用户去疯狂点击甚至是使用恶意脚本去实现疯狂点击按钮
区别 都可以极大的优化网络请求性能,提高用户体验。防抖是延迟执行,而节流是间隔执行。防抖每次触发事件都重置计时器,而节流在计时器到时间后再清空计时器
缺点 每次清除定时器后重新计时,则延时时间则变得更长 短时间内无法联系调用事件函数,只有等上一次触发规定延时过后才能调用

(2)原生JS函数实现

1.防抖函数

function debounce(fn, delay) {    //fn回调函数  delay延迟时间
    let timer = null;    //设置计时器
    return function(){
        let context = this;
        let args = arguments;    //arguments对象对应于传递给函数的参数 e,这里用args保存
        //存在定时器  则重新计时--清除计时器
        if(timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
        //这里setTimeout()形成了闭包,fn中的this指向window,需要改变this指向
        //事件对象 e 在以上方法调用中已被丢弃,为undefined,这里重新传入args
            fn.apply(context,args);
        },delay);
    }
}

2.节流函数

 实现方式一:

function throttle(fn, wait) {
    let timer = null;
    return function() {
        let context = this;
        let args = arguments;
        if (!timer) {
            timer = setTimeout(() => {
                timer = null
                fn.apply(context, args)
            }, wait)
        }

    }
}

实现方式二:使用两个时间戳lasttime旧时间戳nowtime新时间戳,每次触发事件都判断二者的时间差,如果到达规定时间,执行函数并重置旧时间戳

function throttle(fn, wait) {
    var lasttime = 0;
    return function() {
        let nowtime = Date.now();
        let context = this;
        let args = arguments;
        if (nowtime - lasttime > wait) {
            fn.apply(context, args);
            lasttime = nowtime;
        }
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(js,前端面试,js,面试,javascript,es6)