面试官:请手写一个防抖节流🤔,我:在我的博客里写了,想要啊?你去复制就好了😎

防抖节流,前端面试中,考察频率非常高;当然在实际的开发中,许多业务场景经常也会应用到。

如果你还不知道防抖节流是啥的话,或者最近在准备面试但是忘记了,本文将带你再次学习如何手写防抖节流,让你在面试中实现一个简单的防抖节流。😘

防抖

基本概念

只有当事件停止触发一段时间后才会执行函数,确保短时间内多次调用仅执行一次

场景

输入框搜索联想,频繁输入时只在用户停止输入一段时间后发送请求

防抖丐版实现

分析

前面触发的点击事件我们没有去执行,但是到最后一次触发事件后的等待期结束后执行

代码

html 复制代码
<body>
    <button id="btn">提交</button>
    <script>
        const btn = document.querySelector('button')
        function sendMsg(msg) {
            const currentDate = new Date();
            console.log('sendMsg函数的this指向是',this,'\n',
            '点击事件传递进来的参数是',msg,'\n',currentDate.toLocaleString())
        }
        
        btn.addEventListener('click', debounce(sendMsg, 1000))//防抖函数
        // btn.addEventListener('click', sendMsg)//没有防抖的话
        function debounce(fn, delay) {
            let timer
            return function(){
                let args = arguments
                if(timer) clearTimeout(timer)
                
                timer = setTimeout(()=>{
                    fn.call(this,...args )
                },delay)
                
            }
        }
    </script>
</body>

代码讲解

我们使用debounce函数来包裹要执行的函数,传入设置的时间间隔; debounce函数中使用到了闭包来保证多次调用的话timer变量的一致性, 执行一次debounce函数就会对计时器timer变量判断,如果有计时器就重新设定,如果在设定的间隔中触发,那么定时器就会不断刷新,实现最后一次等待之后再触发,来实现防抖效果

这里的call方法和arguments对象

如果需要执行的函数fn如果当中有通过this指向dom对象的代码的话,因为fn函数被节流函数debounce包裹,所以需要使用call来设定正确fnthis指向

又因为函数fn可能也需要依赖点击事件传入的参数,所以通过使用arguments对象来获取到传入debounce函数返回的匿名函数的参数,来确保代码正确运行

效果

没有防抖,触发一次点击事件就立马执行,要执行的函数逻辑

开启防抖,只在最后一次事件触发之后再执行函数

节流

基本概念

节流就是在特定时间间隔内允许函数执行一次,周期性地执行函数,不限制最后一个事件

应用场景

滚动事件监听,实时更新但不密集执行,如滚动加载

还有一个非常常见的场景,就是在打游戏的时候想多打出点伤害,手速通常会很快,但是 游戏中按键连击,只会确保每段时间只触发一次伤害计算

节流丐版实现

分析

节流概括来说就是,按照固定的时间间隔执行,无视触发频率

代码

html 复制代码
<body>
    <button>按钮</button>
    <script>
        let btn = document.querySelector('button')
        function sendMsg(e) {
            const currentDate = new Date()
            console.log('sendMsg的this指向是',this,'\n','点击事件传递进来的参数时',e,'\n',currentDate.toLocaleString())
        }
         btn.addEventListener('click',throttle(sendMsg,1000))//节流函数
         //没有节流
        //btn.addEventListener('click',sendMsg)
        function throttle(fn,wait) {
            let preTime = Date.now()
            return function () {
                let nowTime = Date.now()
                if (nowTime - preTime >= wait) {
                    fn.apply(this,arguments)
                    preTime = nowTime
                }
            }
        }
    </script>
</body>

代码讲解

了解到防抖之后,节流也就非常好理解了

Date.now() 将会得到一个表示自 1970 年 1 月 1 日 00:00:00 UTC 以来所经过的毫秒数的整数值。 这个方法是 Date 对象的一个静态成员函数,意味着你无需创建 Date 对象实例就能调用它

通过闭包设定一个初始时间保证多次调用函数都是这个变量,如果函数的执行时间-初始时间大于或等于设定的时间间隔,则执行函数,并刷新初始时间,否则啥也不干;就可以实现等待设定的时间之后才能触发的节流效果。

这里的arguments对象没有解构是因为apply方法接受数组为参数。

实现效果

使用节流函数,多次点击因为小于设定好的时间间隔所以并不会执行,只有当等待时间等于或者大于设定好的间隔才会执行

还在学习中,水平有限,本文可能存在纰漏或错误,如有问题欢迎指正,感谢你阅读这篇文章,如果你觉得写得还行的话,不要忘记点赞、评论、收藏哦!祝生活愉快!😘

本人目前在准备春招,也希望和一起准备春招的佬们互相交流一下,一起冲刺大厂,欢迎私信评论或加v:guanyiiu1314

相关推荐
regon1 分钟前
第九章 述职11 交叉面试
面试·职场和发展·《打造卓越团队》
小时前端2 分钟前
谁说 AI 历史会话必须存后端?IndexedDB方案完美翻盘
前端·agent·indexeddb
wordbaby6 分钟前
TanStack Router 基于文件的路由
前端
LYFlied6 分钟前
【每日算法】LeetCode 105. 从前序与中序遍历序列构造二叉树
数据结构·算法·leetcode·面试·职场和发展
wordbaby11 分钟前
TanStack Router 路由概念
前端
wordbaby13 分钟前
TanStack Router 路由匹配
前端
cc蒲公英14 分钟前
vue nextTick和setTimeout区别
前端·javascript·vue.js
程序员刘禹锡19 分钟前
Html中常用的块标签!!!12.16日
前端·html
sinat_3842410925 分钟前
OpenSpeedy 是一款开源免费的游戏变速工具
javascript
我血条子呢29 分钟前
【CSS】类似渐变色弯曲border
前端·css