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


    写在前面

    防抖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)
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    上面我尽可能的加了每句的注释,在直接看懂这个函数之前,你需要了解 闭包 ,定时器,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)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

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

    再来给大家看下效果:
    在这里插入图片描述
    另外我把节流的代码段附上,理念相同只是在控制上有所区别,大家可以根据需求扩展函数

    //节流
        function throttle(fn, delay = 300) {
            // delay 秒内执行一次
            let flag = true;
            return function () {
                if (!flag) return;
                flag = false
                setTimeout(() => {
                    fn.apply(this, arguments);
                    flag = true
                }, delay);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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


    最后

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

  • 相关阅读:
    QQ登录的测试用例
    【遥控器开发基础教程3】疯壳·开源编队无人机-ADC(摇杆控制)
    针孔相机投影模型
    〖大前端 - ES6篇②〗- let和const
    vue-element-switch用法
    齐岳定制 FITC荧光素标记果聚糖;FITC-fructan;fructan-FITC;CY3、CY5、CY5.5、CY7、CY7.5标记果聚糖
    Ubuntu安装配置PostgreSQL(18.04)
    无胁科技-TVD每日漏洞情报-2022-8-6
    蓝桥杯python组--基础训练---2、#一个数如果恰好等于它的因子之和,这个数就称为“完数”,;例如:6=1+2+3,找出1000以内的
    C++ 移动构造函数详解
  • 原文地址:https://blog.csdn.net/g18204746769/article/details/127409937