一、核心概念对比
维度 |
防抖(Debounce) |
节流(Throttle) |
定义 |
事件触发后,等待固定时间再执行回调;若期间再次触发,则重新计时。 |
事件触发后,固定时间内只执行一次回调,后续触发被忽略。 |
目标 |
确保高频事件(如输入)的最终结果只触发一次。 |
确保高频事件(如滚动)按固定频率执行。 |
执行时机 |
最后一次触发后的等待时间结束时执行。 |
按固定时间间隔执行(如每秒一次)。 |
类比 |
电梯关门:有人进出时重新计时关门。 |
水龙头滴水:无论拧多快,水滴按固定频率落下。 |
二、代码实现
1. 防抖(Debounce)
javascript
复制代码
function debounce(fn, delay) {
let timer = null;
return function(...args) {
clearTimeout(timer); // 清除之前的计时
timer = setTimeout(() => {
fn.apply(this, args); // 延迟执行
}, delay);
};
}
// 示例:输入框搜索建议
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function(e) {
console.log('发起搜索请求:', e.target.value);
}, 500));
2. 节流(Throttle)
javascript
复制代码
function throttle(fn, interval) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= interval) { // 判断是否达到时间间隔
fn.apply(this, args);
lastTime = now;
}
};
}
// 示例:滚动加载更多
window.addEventListener('scroll', throttle(function() {
console.log('检查滚动位置,加载数据...');
}, 1000));
三、使用场景
场景 |
防抖(Debounce) |
节流(Throttle) |
输入框实时搜索 |
✅ 用户停止输入后发起请求(如500ms无输入) |
❌ 不适合(输入期间仍需响应) |
窗口调整(resize) |
✅ 调整结束后计算布局 |
✅ 按固定频率更新布局(如每秒一次) |
按钮防重复点击 |
✅ 避免用户快速点击多次提交 |
✅ 固定时间内只允许提交一次 |
滚动事件(scroll) |
❌ 最后一次滚动后触发可能不符合预期 |
✅ 滚动期间定期检查位置(如触底加载) |
鼠标移动(mousemove) |
❌ 需要连续响应时不适用 |
✅ 限制高频更新(如拖拽元素时降低渲染频率) |
四、高频面试问题
1. 如何手写防抖和节流?
- 参考上述代码实现,注意闭包和
apply
绑定上下文。
2. 防抖和节流的本质区别是什么?
- 防抖关注"最后一次触发后的结果",节流关注"固定间隔内的执行频率"。
3. 如何选择防抖或节流?
- 防抖:适合结果导向型场景(如搜索建议、提交按钮)。
- 节流:适合过程控制型场景(如滚动加载、实时定位)。
4. 防抖的立即执行版本如何实现?
-
添加参数控制是否立即执行第一次触发:
javascript
复制代码
function debounce(fn, delay, immediate) {
let timer = null;
return function(...args) {
if (immediate && !timer) {
fn.apply(this, args); // 立即执行
}
clearTimeout(timer);
timer = setTimeout(() => {
if (!immediate) fn.apply(this, args);
timer = null;
}, delay);
};
}
五、常见误区
- 过度依赖第三方库 :虽然Lodash的
_.debounce
和_.throttle
功能完善,但面试需掌握原生实现。
- 忽视this和参数绑定 :回调函数中需正确传递
this
和事件参数(如event
)。
- 时间间隔设置不合理:防抖的延迟过长会导致响应迟钝,节流的间隔过短会失去优化意义。
六、总结回答技巧
- 一句话概括 :
"防抖是延迟执行,确保连续触发只执行最后一次;节流是限频执行,确保连续触发按固定频率执行。"
- 结合项目举例 :
"在商品搜索页中,输入框用防抖减少请求次数;图片懒加载用节流控制滚动检查频率。"
- 扩展思考 :
"防抖和节流本质是闭包的应用,通过控制计时器和时间戳管理事件触发逻辑。"