在 JavaScript 中,防抖(Debounce) 和 节流(Throttle) 是两种常用的优化高频率事件处理(如 resize、scroll、input 等)的技术。它们都利用了 闭包 的特性来保存状态。
一、防抖(Debounce)
原理:在事件被触发后,等待一段时间(比如 500ms),如果在这段时间内没有再次触发事件,就执行函数;如果再次触发了,则重新计时。
实现(使用闭包):
function debounce(fn, delay) {
let timer = null;
return function (...args) {
// 清除上一次的定时器
clearTimeout(timer);
// 设置新的定时器
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}使用示例:
const handleInput = debounce(function (value) {
console.log('输入内容:', value);
}, 500);
// 模拟频繁输入
handleInput('a');
handleInput('ab');
handleInput('abc'); // 只有最后一次会执行(500ms 后)二、节流(Throttle)
原理:在一定时间间隔内,最多只执行一次函数。即使事件频繁触发,也保证函数按固定频率执行。
实现(使用闭包 + 时间戳):
function throttle(fn, delay) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
}
};
}也可以用
setTimeout实现“延迟执行”的节流,但上述时间戳方式更常用且响应更快。
使用示例:
const handleScroll = throttle(function () {
console.log('滚动了!');
}, 1000);
// 模拟频繁滚动
window.addEventListener('scroll', handleScroll);三、对比总结
| 特性 | 防抖(Debounce) | 节流(Throttle) |
|---|---|---|
| 执行时机 | 事件停止触发后执行一次 | 固定时间间隔内最多执行一次 |
| 适用场景 | 搜索框输入、窗口 resize | 滚动加载、按钮点击限制、mousemove |
| 是否立即执行 | 默认延迟后执行(可改造成立即) | 可控制是否首/尾执行 |
四、进阶:带 immediate 参数的防抖(立即执行版)
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);
};
}

0条评论
点击登录参与评论