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

手撕防抖节流

前言

每日一篇快乐每一天

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

在这里插入图片描述

防抖

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

防抖:让事件在触发后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)
            }
        }
    }

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

    // 简单版防抖函数,添加立即执行,当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()
            }
        }
    }

那么我们平时在使用中的防抖函数肯定不会这么简单,还得传参绑定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)
            }
        }
    }

节流

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

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

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

最终版

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

面试相关

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

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

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

防抖为例

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

闭包有两个特点

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

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

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值