javaScript 防抖/节流,探索学习,对新手友好的内容

时间:2022-10-20 12:54:14

写在前面

防抖:debounce, 节流 : throttle ;这俩个名词大家都不陌生,不管是学习,面试,笔试,偶尔总要提提,网上的参考文献也是大有篇章,其中有好多优秀的文章都写的很好了,大家都可以参考的来理解,我们的目的只有一个,那就是理解,并学习,从而创新。我的目的就是从保姆的角度来解释一下这俩个技术,以便大家容易理解;


应用场景

这俩个技术主要是用于web实践中对于事件执行时间的把控,如windows的input,mouse相关事件,keyup等,对于这俩个名词分别解释为:防抖(debounce):一段时间后执行一次节流(throttle):一段时间内执行一次;这样还好理解一点吧,下面我们通过一段实例来解析下俩个东西,重点以防抖为对象,节流只是控制开关有别;


实战解析

先看一段防抖代码,这是我光明正大从其他博主那复制来的

function debounce(fn, delay = 300) {
        // delay 秒后执行一次
        let timer = null; //定时器开关,利用闭包保存变量
        return function () {
            clearTimeout(timer);
            timer = setTimeout(() => {
                //this:让函数获得调用者的指向
                //arguments:函数的参数,由于此处无法断言
                //故用argument
                fn.apply(this, arguments);
            }, delay)
        }
    }

上面我尽可能的加了每句的注释,在直接看懂这个函数之前,你需要了解 闭包 ,定时器,apply函数
这里我做个简单的解释:

  1. 闭包的作用:通过一系方法,将函数内部的变量(局部变量)转化为全局变量。我们这里return 的函数就形成了闭包,并且拥有了timer变量
  2. 定时器就是延迟多少秒后执行一次,也有循环定时器和立即执行器;
  3. apply函数可以理解为替调用者传递一个作用域this指向,及参数列表,属于javascript的高阶函数,这里我推荐一个学习文章:apply函数

介绍完了以上技术,我再以我的理解叙述下这个函数的执行特征:

  1. debounce函数在调用后会返回一个带有定时器的函数
  2. 这个函数在一定时间后执行,也就是我们的delay参数
  3. 这个函数在执行时会调用传入的fn函数

为什么调用fn函数需要使用apply来改变this指向呢?
帅气的人回答:这就与我们需要防抖的场景密切相关,例如input事件,该事件会执行一个传入的函数,并且附带回调参数event; 如果不用apply,那防抖函数的作用域里就访问不到这俩个最有用的东西了。

下面看我的例子

let input = document.getElementById('input');
input.addEventListener('input',debounce(search,1000))
//防抖回调执行函数,这个函数在防抖函数执行后,根据delay执行
function search(e){
    console.log(e); //这里可以拿到e,要归功于apply的arguments参数
    console.log(this);//这里可以拿到this,要归功于apply的this参数
    this.style.padding="20px";
}
//防抖
function debounce(fn, delay = 300) {
    // delay 秒后执行一次
    let timer = null;
    return function () {
        clearTimeout(timer);
        timer = setTimeout(() => {
            //this:让函数获得调用者的指向
            //arguments:函数的参数,由于此处无法断言
            //故用argument
            fn.apply(this, arguments); 
        }, delay)
    }
}

fn.apply(this, arguments); 这里的this到底是谁的this? 这是我最大的疑问,也是发这篇文章最想说的话,谁最后一次调用的debounce This就是谁的,我们绑定的是input的事件,那input调用的回调函数,this就是input的。

再来给大家看下效果:
javaScript 防抖/节流,探索学习,对新手友好的内容
另外我把节流的代码段附上,理念相同只是在控制上有所区别,大家可以根据需求扩展函数

//节流
    function throttle(fn, delay = 300) {
        // delay 秒内执行一次
        let flag = true;
        return function () {
            if (!flag) return;
            flag = false
            setTimeout(() => {
                fn.apply(this, arguments);
                flag = true
            }, delay);
        }
    }

看到这里,如果你理解了,你将会对apply函数应用,闭包函数,有更好的理解,相关于apply函数的还有call(),bind()等高阶函数,均属于一个类型,但是它们的使用场景不同,这里不再扩展。


最后

???? javascript专栏
☃️ 个人简介:一个喜爱技术,喜欢探索的人。
???? 励志格言: 脚踏实地,虚心学习,相信自己的配得上所有美好。
❗如果文章还可以,记得用你可爱的小手点赞????关注✅,我会在第一时间回关。