标准答案
- 防抖 debounce 的核心是每次触发都清理旧定时器,并重新计时。
- 节流 throttle 的核心是在一段时间内限制执行频率。
- 防抖关注最后一次,节流关注固定频率。
- 实现时要透传 this 和参数,否则事件回调或对象方法会出问题。
- 完整版本还可以支持立即执行、取消执行和尾部执行。
题目解析
防抖和节流都处理高频触发,但业务含义不同。搜索框输入中间态通常不需要请求,所以适合防抖;滚动位置需要持续反馈,只是不能太频繁,所以适合节流。
手写实现不能只写 setTimeout。真实回调常依赖事件对象、当前 this 和最新参数,这些都需要从包装函数传进去。
组件卸载时还要清理定时器。否则延迟执行的回调可能在页面离开后继续修改状态,造成警告或脏数据。
代码示例
基础版本先覆盖延迟执行、固定频率、this 和参数透传。
JavaScript
function debounce(fn, delay) {
let timer = null
return function debounced(...args) {
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
function throttle(fn, wait) {
let lastTime = 0
return function throttled(...args) {
const now = Date.now()
if (now - lastTime >= wait) {
lastTime = now
fn.apply(this, args)
}
}
}常见误区
- 把防抖和节流的适用场景说反。
- 只写定时器逻辑,忘记透传 this 和参数。
- 组件卸载或页面离开时没有清理未执行的防抖回调。