【前端每天一题】🔥 第 9 题:防抖(debounce)与节流(throttle)的区别?如何实现?

196 阅读2分钟

防抖与节流 - 前端高频面试题

本题属于前端工程师几乎"必问"的那类:防抖与节流

第 9 题:防抖(debounce)与节流(throttle)的区别?如何实现?


一、面试官期待的关键点

⭐ 1. 防抖(Debounce)

含义:一定时间内只执行最后一次。

  • 用户停止触发后 N 毫秒再执行
  • 连续触发时会不断"重新计时"
  • 常用于:
    • 搜索框输入
    • 窗口 resize
    • 表单实时校验
➤ 防抖示意图
触发 → 重置 → 重置 → … → 停止 → 执行
➤ 防抖实现(面试必写)
function debounce(fn, delay) {
  let timer = null
  return function (...args) {
    clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

⭐ 2. 节流(Throttle)

含义:规定时间内只执行一次。

  • 每隔 N 毫秒执行一次动作
  • 无论触发多少次
  • 常用于:
    • 滚动事件
    • 页面 resize
    • 高频拖拽事件
➤ 节流示意图
触发 → 执行 → 冷却中 → 执行
➤ 节流实现(时间戳版)
function throttle(fn, delay) {
  let last = 0
  return function (...args) {
    const now = Date.now()
    if (now - last >= delay) {
      last = now
      fn.apply(this, args)
    }
  }
}

二、两者的根本区别(面试官最爱听)

特性防抖 debounce节流 throttle
执行次数高频触发下 只执行一次高频触发下 每隔固定时间执行一次
使用场景用户输入校验、防止重复提交滚动监听、拖拽、窗口 resize
实现原理setTimeout + 清除定时器时间戳或定时器

三、手写带立即执行版本(加分)

🔹 防抖(立即执行版)

输入时立刻响应(如实时提示)

function debounce(fn, delay, immediate = false) {
  let timer = null

  return function (...args) {
    const callNow = immediate && !timer
    clearTimeout(timer)

    timer = setTimeout(() => {
      timer = null
      if (!immediate) fn.apply(this, args)
    }, delay)

    if (callNow) fn.apply(this, args)
  }
}

四、速记卡片(上班摸鱼记忆版)

🎯 防抖:只执行最后一次(停止后执行)
📌 用于:输入框、实时校验
🧠 原理:setTimeout + clearTimeout

🎯 节流:固定间隔执行
📌 用于:滚动、拖拽、resize
🧠 原理:时间戳或定时器

⭐ 防抖 = "等你不动再说"
⭐ 节流 = "一秒说一次"