防抖与节流 - 前端高频面试题
本题属于前端工程师几乎"必问"的那类:防抖与节流
第 9 题:防抖(debounce)与节流(throttle)的区别?如何实现?
一、面试官期待的关键点
⭐ 1. 防抖(Debounce)
含义:一定时间内只执行最后一次。
- 用户停止触发后 N 毫秒再执行
- 连续触发时会不断"重新计时"
- 常用于:
- 搜索框输入
- 窗口 resize
- 表单实时校验
➤ 防抖示意图
触发 → 重置 → 重置 → ... → 停止 → 执行
➤ 防抖实现(面试必写)
javascript
function debounce(fn, delay) {
let timer = null
return function (...args) {
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
⭐ 2. 节流(Throttle)
含义:规定时间内只执行一次。
- 每隔 N 毫秒执行一次动作
- 无论触发多少次
- 常用于:
- 滚动事件
- 页面 resize
- 高频拖拽事件
➤ 节流示意图
触发 → 执行 → 冷却中 → 执行
➤ 节流实现(时间戳版)
javascript
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 + 清除定时器 |
时间戳或定时器 |
三、手写带立即执行版本(加分)
🔹 防抖(立即执行版)
输入时立刻响应(如实时提示)
javascript
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)
}
}
四、速记卡片(上班摸鱼记忆版)
javascript
🎯 防抖:只执行最后一次(停止后执行)
📌 用于:输入框、实时校验
🧠 原理:setTimeout + clearTimeout
🎯 节流:固定间隔执行
📌 用于:滚动、拖拽、resize
🧠 原理:时间戳或定时器
⭐ 防抖 = "等你不动再说"
⭐ 节流 = "一秒说一次"