当前位置: 首页 > news >正文

【每日一面】手写防抖函数

基础问答

问:手写一个防抖函数
答:

/*** 基础版防抖函数(非立即执行)* @param {Function} func - 需要防抖的目标函数* @param {number} delay - 等待时间(毫秒)* @returns {Function} - 防抖后的函数*/
function debounce(func, delay) {let timer = null; // 用闭包存储定时器ID,确保多次调用共享同一个定时器// 返回防抖后的函数,接收目标函数的参数(...args)return function (...args) {// 1. 若已有定时器,先清除(重复触发时重新计时)if (timer) clearTimeout(timer);// 2. 重新设置定时器,等待delay后执行目标函数timer = setTimeout(() => {func.apply(this, args); // 用apply绑定this(确保目标函数this指向正确)timer = null; // 执行后清空定时器,避免内存泄漏}, delay);};
}

扩展延伸

防抖(Debounce)

  • 核心逻辑:当一个事件会被频繁的触发时,防抖函数不会频繁的执行,而是等待事件停止触发一段时间后才执行;如果在等待执行的过程中,事件再次被触发,则我们需要重新计算需要等待的时间。
  • 典型使用场景:搜索框输入联想(每次按键都会触发输入对应 Input 的事件,我们认为用户结束输入后,我们再进行联想,这个结束输入的判定规则就是,自上一次Input事件触发后的一段时间内,用户没有再触发Input事件,可视为结束输入,需要开始联想),实时输入校验等。

和防抖并列提及的是节流。

节流(Throttle)

  • 核心逻辑:当事件会被频繁触发的时候,节流函数只会按照固定的时间间隔执行,无论期间事件被处罚多少次,都只在每个时间的开头(或结束)执行一次。
  • 典型使用场景:滚动监听(一般用于加载数据判断,每隔一段时间判断一次当前位置,来判断需要加载的数据量),窗口resize事件(用于重新计算布局)

这里简单对比一下防抖和节流:

防抖 节流
执行时机 事件停止触发后,等待一段指定的时间 固定时间间隔执行,每个时间段内仅执行一次
重复触发的问题 重新计算等待的时间,执行会延迟 不影响,固定时间间隔执行
目标 解决冗余的执行 解决过度的执行
使用场景 搜索、校验 滚动加载

搜索输入的过程中,每次键入字符触发搜索,在没有防抖的情况下,仅仅只有最后一次的搜索(即用户输入完成)才是有效的,之前的这些,全部都是没有意义的,只会加重服务负担,即为 “冗余”

页面滚动过程中,滚动是持续触发的,在没有节流的情况下,每一次滚动都会有大量的计算过程(假设你的滚动事件是有计算操作的),计算阻塞主线程,会导致页面卡顿,无法正常滚动,即为 “过度” ,如果使用防抖,滚动事件的持续触发,会导致计算一直无法开始,俗称“不跟手”。

面试追问

  1. setTimeout 的延时并不准,有没有办法实现一个更精确的时间检测?
    有,使用时间戳 + requestFrameAnimation 实现。

  2. 页面滚动加载数据一般用什么?搜索框输入触发联想词,又用什么?
    滚动加载一般用节流,防抖需要等用户停止滚动才加载,可能会等很久,节流则是一到底部就加载,可以保证加载的及时性。
    搜索联想一般用防抖,因为用户的输入过程会频繁触发联想,但是只有用户停止输入时,触发的联想才是用户想要的、有效的。

  3. 我看你在防抖函数中,用了 apply 这是为啥?为啥不可以直接用 func ?
    主要是 this 指针的指向问题,防抖函数返回的是一个新的函数,假设现在设置的是 input.oninput = debounceSearch,这个 debounceSearch 中如果有 this,那么预期是要指向 input 标签,但是我们直接调用 func 的话,this 会指向 window 或 undefined,和预期不一致。

  4. 防抖函数中,如果目标函数有返回值,我们可以拿到吗?
    不行,即使返回目标函数结果也不行,因为他在 setTimeout 里面执行的,无法返回对应的执行结果。

  5. 但是我就需要这个返回结果,有没有办法?
    有,两种办法,一是将 setTimout 用 Promise 封装起来,setTimeout 的回调执行时,resolve 这个 Promise 就可以了,这样防抖函数就变成了一个异步的api,二是使用回调参数,在目标函数执行后,调用这个回调就可以了。

  6. 有没有遇到过防抖函数导致内存泄漏的情况?
    没有,但是防抖函数有内存泄漏的可能性,本质上是闭包写法产生的,编写代码的时候注意闭包的处理就可以了。

http://www.jsqmd.com/news/23248/

相关文章:

  • 最佳技术文档解决方案:用 PandaWiki 打造智能化产品文档体系
  • 模拟Ajax获取数据。表格显示, 带有分页功能,支持翻页,每页显示8行数据。响应式设计,适配不同屏幕尺寸
  • 2025年10月北京工装设计公司推荐榜:五强对比评测
  • 苏州GEO企业深度解析:行业中如何选择专业服务商 - 勤懒调和者
  • 高效便捷的安全数据交换系统,助力企业合规管理
  • 2025年10月北京工装设计公司排名:五家对比指南
  • 2025年10月防爆振动变送器厂家推荐:实力榜对比指南
  • 跨网文件交换怎么实现审批?从需求到落地的全解析!
  • MySQLDay5(基础篇完结)
  • 2025 年优质球墨铸铁管厂家最新推荐榜,技术实力与市场口碑深度解析
  • HTML之addEventListener示例
  • 2025 年茶叶行业优质品牌最新推荐榜,企业综合实力与市场口碑深度解析
  • 2025年10月北京写字楼装修公司推荐榜:筑垒领衔五强对比
  • 苏联复变函数论专家和教育家Б. В. 沙巴特
  • 2025年蕾蒂蔻品牌深度解析:渐进式自然美学下的科研质控全景
  • 指针的用法,函数,结构体,以及部分解释
  • 【深度解读】文件摆渡系统如何保障数据安全,减少数据泄露风险?
  • 2025年10月北京办公楼施工公司排名榜:精选五强
  • 2025年蕾蒂蔻产品深度解析:械字号轻医美供应链安全全景拆解
  • 一些看到的有趣玄学
  • 2025年10月北京工装设计公司推荐榜:筑垒领衔五强对比
  • 2025年10月绩效管理咨询公司推荐:实力榜对比评价
  • 《手搓》TaskFactory带你安全的起飞
  • 告别 “专业壁垒”:MyEMS 如何让一线操作工也能看懂能耗、发现浪费?
  • 2025年10月山东AI公司推荐榜:优立德领衔五强对比
  • AI 超级智能体全栈方案阶段四:学术分析 AI 项目 RAG 落地指南:基于 Spring AI 的本地与阿里云知识库实践
  • 2025年10月绩效管理咨询公司推荐:五家对比评价报告
  • 2025 年砂浆源头厂家最新推荐排行榜:聚焦防水抗裂等多类型砂浆,精选优质实力企业助力工程采购
  • 网络断网、环路、IP 冲突?VRRP+MSTP+DHCP 联动便捷的方案一次性消除
  • 2025 年过滤机厂家最新推荐榜,技术实力与市场口碑深度解析,筛选高性能适配多行业需求品牌