JavaScript 中的防抖 vs 节流(简明代码解释)
发布: (2025年12月13日 GMT+8 09:08)
3 min read
原文: Dev.to
Source: Dev.to

如果你长期使用 JavaScript,你会遇到事件触发频率过高的情况——例如 input 在每次按键时都会触发,scroll 每秒触发数十次,或者在拖动窗口时 resize 持续触发。每次事件都执行昂贵的逻辑会影响性能。这时 防抖(debounce) 和 节流(throttle) 就派上用场了。
防抖(Debounce)——在用户停止后执行
防抖 会延迟函数的执行,直到用户 停止触发事件 达到指定的时间后才执行。
常见使用场景
- 搜索输入框
- 表单校验
- 自动保存
- 输入时的 API 调用
JavaScript 实现
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
使用示例(搜索输入框)
const search = debounce((text) => {
console.log("Searching for:", text);
}, 500);
input.addEventListener("input", (e) => {
search(e.target.value);
});
发生了什么?
- 每一次按键都会清除之前的计时器。
- 然后启动一个新的计时器。
- 如果用户持续输入,函数永远不会执行。
- 一旦停止输入,函数会 只执行一次。
节流(Throttle)——固定间隔执行
节流 确保函数 最多每 X 毫秒执行一次,不论事件触发了多少次。
常见使用场景
- 滚动事件
- 窗口大小变化事件
- 拖拽
- 防止按钮连点
JavaScript 实现
function throttle(fn, limit) {
let isLocked = false;
return function (...args) {
if (isLocked) return;
fn(...args);
isLocked = true;
setTimeout(() => {
isLocked = false;
}, limit);
};
}
使用示例(滚动)
const handleScroll = throttle(() => {
console.log("Scrolling...");
}, 1000);
window.addEventListener("scroll", handleScroll);
发生了什么?
- 第一次事件立即执行。
- 函数进入锁定状态。
- 锁定期间的所有事件都会被忽略。
- 超过时间限制后函数解锁,允许下一次调用。
防抖 vs 节流(快速对比)
| 特性 | 防抖(Debounce) | 节流(Throttle) |
|---|---|---|
| 函数何时执行 | 用户停止后 | 固定间隔 |
| 额外的事件 | 被取消 | 被忽略 |
| 执行方式 | 延迟执行 | 立即执行 |
| 适用场景 | 输入、搜索 | 滚动、窗口大小变化 |
简单记忆法
Debounce → clear + wait
Throttle → lock + release
最后思考
防抖和节流都是小工具,但它们对以下方面有 巨大影响:
- 性能
- 用户体验
- API 效率
了解 何时使用哪种 能帮助你编写更好、更响应迅速的 JavaScript。
祝编码愉快!