js防抖和节流实现
防抖(Debounce)
防抖的核心思想是在事件触发后延迟执行回调函数,若在延迟时间内再次触发事件,则重新计时。适用于输入框搜索联想、窗口大小调整等场景。
function debounce(fn, delay) {
let timer = null;
return function() {
const context = this;
const args = arguments;
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context, args);
}, delay);
};
}
节流(Throttle)
节流的原理是在固定时间间隔内只执行一次回调函数。适用于滚动事件、高频点击按钮等场景。
function throttle(fn, interval) {
let lastTime = 0;
return function() {
const context = this;
const args = arguments;
const now = Date.now();
if (now - lastTime >= interval) {
fn.apply(context, args);
lastTime = now;
}
};
}
时间戳与定时器结合的节流
结合时间戳和定时器实现更精确的节流,确保最后一次触发能执行回调。

function throttle(fn, interval) {
let lastTime = 0;
let timer = null;
return function() {
const context = this;
const args = arguments;
const now = Date.now();
const remaining = interval - (now - lastTime);
if (remaining <= 0) {
if (timer) {
clearTimeout(timer);
timer = null;
}
fn.apply(context, args);
lastTime = now;
} else if (!timer) {
timer = setTimeout(() => {
fn.apply(context, args);
lastTime = Date.now();
timer = null;
}, remaining);
}
};
}
使用示例
// 防抖示例
const debouncedSearch = debounce(function(query) {
console.log('Searching for:', query);
}, 500);
document.getElementById('search').addEventListener('input', (e) => {
debouncedSearch(e.target.value);
});
// 节流示例
const throttledScroll = throttle(function() {
console.log('Scrolled');
}, 1000);
window.addEventListener('scroll', throttledScroll);
区别与应用场景
- 防抖:连续触发事件时,只在最后一次触发后执行回调。适用于输入框实时搜索、表单验证等场景。
- 节流:固定时间间隔内只执行一次回调。适用于滚动加载、高频点击等场景。
两种方法均通过闭包保存状态,避免全局污染。实际开发中可根据需求选择或结合使用。






