深入理解 JavaScript 的防抖(debounce)与节流(throttle)——原理 + 手写实现 + 场景实战

在前端开发中,input 输入、滚动、窗口 resize、点击、鼠标移动...这些高频触发的事件,处理不好,极容易出现:

  • 页面卡顿

  • 接口狂发

  • 浏览器崩溃

  • 用户体验极差

所以,防抖(debounce)和节流(throttle)这两个小工具,就变得特别重要。

一句话理解

名称核心思想应用场景
防抖 debounce多次触发,最后一次生效搜索输入、自动保存
节流 throttle固定时间内只触发一次滚动加载、按钮点击

debounce 防抖原理详解

关键:如果事件连续触发,就清除定时器,只有停止触发一段时间后才执行。

手写版 debounce

function debounce(fn, delay) {
  let timer = null
  return function(...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

用法示例

window.addEventListener('resize', debounce(() => {
  console.log('窗口大小变化完成')
}, 500))

效果:

  • 快速 resize -> 不会连续打印

  • 停下来 500ms -> 才会触发

 

throttle 节流原理详解

关键:一段时间内,只允许触发一次

手写版 throttle

function throttle(fn, delay) {
  let last = 0
  return function(...args) {
    const now = Date.now()
    if (now - last > delay) {
      last = now
      fn.apply(this, args)
    }
  }
}

用法示例

window.addEventListener('scroll', throttle(() => {
  console.log('滚动中')
}, 300))

场景实战对比

场景用 debounce用 throttle
搜索框输入×
滚动监听×
防止多次点击提交×
窗口resize×
表单自动保存×

手写加强版:支持立即执行的 debounce

有时候希望:

  • 输入开始就触发一次(立即执行)

  • 然后防抖后再触发

function debounce(fn, delay, immediate = false) {
  let timer = null
  return function(...args) {
    if (timer) clearTimeout(timer)

    if (immediate && !timer) {
      fn.apply(this, args)
    }

    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值