js中防抖和节流实现
防抖(Debounce)实现
防抖的核心思想是在事件触发后延迟执行回调函数,若在延迟时间内再次触发事件,则重新计时。适用于输入框搜索联想、窗口大小调整等场景。
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
使用示例:
const handleInput = debounce(() => {
console.log('Input debounced');
}, 300);
document.querySelector('input').addEventListener('input', handleInput);
节流(Throttle)实现
节流的原理是在固定时间间隔内只执行一次回调函数。适用于滚动事件、鼠标移动等高频触发场景。

时间戳版本(立即执行):
function throttle(func, limit) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= limit) {
func.apply(this, args);
lastTime = now;
}
};
}
定时器版本(延迟执行):

function throttle(func, limit) {
let timeoutId;
return function(...args) {
if (!timeoutId) {
timeoutId = setTimeout(() => {
func.apply(this, args);
timeoutId = null;
}, limit);
}
};
}
结合版本(首尾都执行):
function throttle(func, limit) {
let lastTime = 0;
let timeoutId;
return function(...args) {
const now = Date.now();
const remaining = limit - (now - lastTime);
if (remaining <= 0) {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
func.apply(this, args);
lastTime = now;
} else if (!timeoutId) {
timeoutId = setTimeout(() => {
func.apply(this, args);
timeoutId = null;
lastTime = Date.now();
}, remaining);
}
};
}
使用示例:
const handleScroll = throttle(() => {
console.log('Scroll throttled');
}, 200);
window.addEventListener('scroll', handleScroll);
关键区别
防抖在连续触发时只会执行最后一次,而节流会按照固定频率执行。根据具体场景需求选择合适的方法:
- 防抖适合处理最终状态(如搜索输入完成)
- 节流适合处理过程状态(如滚动位置更新)






