• 你知道防抖和节流与闭包的关系吗?


    手撕防抖节流

    前言

    每日一篇快乐每一天

    笔者最近发现啊,虽然平时说防抖节流都知道是什么作用,但是突然让你手写,我的脑子就是…,然后默默的打开百度,平时手写一些代码还是很有必要的。所以今天就来彻底把防抖节流扒个精光.(怎么感觉有点变态…[痴汉脸])

    在这里插入图片描述

    防抖

    率先登场是我们的帅小伙防抖小哥,那么`防抖小哥有什么能力呢?

    防抖:让事件在触发后N秒后执行,如果在N秒内重新触发,则重新计算时间。

    有什么应用场景?

    • 按钮双击,我们平时电脑上快速双击就有可能触发两次点击事件
    • 输入框的input或者change时间
    • 轮动条

    等等应用的场景很多,那么我们接下来我们就来手撕

    首先防抖小哥可以有两个版本分比为:立即执行版非立即执行版

    非立即执行版: 主要原理就是再次触发方法的时候把上次的计时器清除掉

        // 简单版,实现了防抖的功能,无法传参
        // 其实防抖和节流都是闭包 后面再讨论
        function debounce(func, time = 2000) {
            // 第一次执行 timer =null
            let timer = null;
            // 这里为什么声明一个timer?  因为debounce返回了一个函数,而函数内部访问了timer这个变量,这样会导致timer不会被回收
            // 这也是使得第二次执行的时候为什么timer不会再次为null
            return function () {
                // 第一次执行肯定为null所以进入
                if (!timer) { 
                    // timer此时不为空了
                    timer = setTimeout(() => {
                        func(); // 执行外部传来的函数
                        timer = null; // 再次把timer设为null 使得函数可以再次执行
                    }, time)
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    立即执行版防抖: 个人认为立即执行版防抖与节流类似了,所以说立即执行版防抖其实没有必要(这里就不再详细注释了)

        // 简单版防抖函数,添加立即执行,当immediate为true的时候执行
        function debounce(func, time = 2000, immediate = true) {
            let timer = null;
            return function () {
                if (!timer) { // 如果再次触发则清空.
                    timer = setTimeout(() => {
                        !immediate && func();
                        timer = null;
                    }, time)
                    immediate && func()
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    那么我们平时在使用中的防抖函数肯定不会这么简单,还得传参绑定this,其实也是很简单把原本的调用方法的方式转换一个换用apply

    最终版防抖函数

        // 最终版,实现了防抖的功能,无法传参
        // 其实防抖和节流都是闭包 后面再讨论
        function debounce(func, time = 2000) {
            // 第一次执行 timer =null
            let timer = null;
            // 这里为什么声明一个timer?  因为debounce返回了一个函数,而函数内部访问了timer这个变量,这样会导致timer不会被回收
            // 这也是使得第二次执行的时候为什么timer不会再次为null
            return function (...args) { // 传参
                // 第一次执行肯定为null所以进入
                if (!timer) {
                    // timer此时不为空了
                    timer = setTimeout(() => {
                        func.apply(this, args) // 执行外部传来的函数
                        timer = null; // 再次把timer设为null 使得函数可以再次执行
                    }, time)
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    节流

    节流: 在规范时间内,只能触发一次函数,如果多次触发不会执行。

    如果弄懂了防抖的话其实节流也差不多,只是计算的方式不同而已,

    节流在防抖的基础上: 多判断了一个条件,第二次触发的时候,如果在规定的时间内,则什么也不执行.

    最终版

        // 简单版,节流其实就比防抖多了一步
        function throttle(func, time) {
            let timer = null;
            return function (...args) {
                if (timer) {// 第二次触发的时候,
                    //节流:如果还在规定的时间内,则什么也不执行
                    //防抖: 重新计时
                    return;
                }
                timer = setInterval(() => {
                    timeout = null;
                    func.apply(this, args)
                }, time)
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    面试相关

    笔者在一次面试中就被问到了,防抖和节流与闭包有什么关系?

    好在面试官是在问了闭包原理后问的防抖和节流,我一下醒悟过来

    今天我们就来盘一盘,闭包防抖以及节流有什么关系

    防抖为例

    首先是闭包原理: 闭包是一个函数,有什么用? 这个函数可以让我们访问某个函数内部的变量

    闭包有两个特点

    • 可以读取函数内部的变量
    • 可以让访问的变量一直保存在内存中

    那我们回过头来看看我们的防抖函数

    在这里插入图片描述

  • 相关阅读:
    ThreadLocal
    从0到1搭建大数据平台之数据计算
    壁挂式新风机市场现状及未来发展趋势分析
    开源Excel 处理工具库MyExcel介绍以及简单例子
    redis面试题(总结)
    grid项目属性之grid-area&justify-self/align-self
    JS逆向 | 推特x-guest-token
    【mysql】innodb_locks不能存在
    使用弹簧启动和 JPA 测试乐观锁定处理
    遭到黑客DDos攻击怎么办??
  • 原文地址:https://blog.csdn.net/lin1072368472/article/details/126316257