防抖函数的核心是延迟执行并重置计时,适用于搜索建议等场景。具体实现通过settimeout延迟触发函数,若再次触发则清除原定时器并重新计时。对于需要立即执行的情况,可引入isinvoked变量控制首次执行。同时可通过添加cancel方法实现手动取消。使用apply确保上下文和参数正确传递。防抖与节流的区别在于防抖保证最后一次触发有效,而节流确保一段时间内仅执行一次。常见应用场景包括搜索建议、窗口调整、按钮防重复点击、文本自动保存等。

防抖函数的核心在于:在事件触发后,不是立即执行,而是等待一段时间,如果在这段时间内再次触发,就重新计时。最终只执行最后一次触发。

防抖的本质是延迟执行,并且在延迟的过程中,如果再次触发,则重新计时。理解这一点,实现防抖就变得简单了。

function debounce(func, delay) {
let timeoutId;
return function(...args) {
const context = this;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(context, args);
}, delay);
};
}
// 示例
function sayHello(name) {
console.log(`Hello, ${name}!`);
}
const debouncedHello = debounce(sayHello, 300);
// 模拟事件触发
debouncedHello("Alice");
debouncedHello("Bob");
setTimeout(() => debouncedHello("Charlie"), 200); // 会取消Bob的执行
setTimeout(() => debouncedHello("David"), 500); // 延迟500ms,会执行有时候,我们希望第一次触发事件时立即执行,而不是等待。可以修改防抖函数来实现:

function debounceImmediate(func, delay) {
let timeoutId;
let isInvoked = false;
return function(...args) {
const context = this;
if (!isInvoked) {
func.apply(context, args);
isInvoked = true;
}
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
isInvoked = false;
}, delay);
};
}
// 示例
function sayHelloImmediate(name) {
console.log(`Hello (Immediate), ${name}!`);
}
const debouncedHelloImmediate = debounceImmediate(sayHelloImmediate, 300);
debouncedHelloImmediate("Eve"); // 立即执行
debouncedHelloImmediate("Frank"); // 不会立即执行,但会重置计时
setTimeout(() => debouncedHelloImmediate("Grace"), 500); // 延迟500ms后执行关键在于引入一个isInvoked变量,控制首次是否立即执行。这种方式适用于需要立即响应的场景,例如搜索框输入。
某些情况下,我们需要手动取消防抖函数的执行。可以给防抖函数添加一个cancel方法:
function debounceWithCancel(func, delay) {
let timeoutId;
function debounced(...args) {
const context = this;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(context, args);
}, delay);
}
debounced.cancel = () => {
clearTimeout(timeoutId);
};
return debounced;
}
// 示例
function sayHelloCancelable(name) {
console.log(`Hello (Cancelable), ${name}!`);
}
const debouncedHelloCancelable = debounceWithCancel(sayHelloCancelable, 300);
debouncedHelloCancelable("Henry");
setTimeout(() => debouncedHelloCancelable.cancel(), 200); // 取消执行
setTimeout(() => debouncedHelloCancelable("Ivy"), 500); // 延迟500ms,会执行这种方式为防抖函数提供了一个额外的控制手段,可以在需要的时候阻止函数的执行。
使用apply可以确保函数在正确的上下文中执行,并传递正确的参数。apply允许我们指定this的值(即上下文)和参数数组。这在处理事件监听器等场景时非常重要,因为我们需要确保函数在触发事件的元素上下文中执行。如果直接调用func(),this的值可能会指向全局对象(例如window),导致错误。
防抖和节流都是为了优化性能,减少函数执行频率的技术,但它们的策略不同。
简单来说,防抖是“最后一次有效”,节流是“一段时间内只执行一次”。
以上就是js如何实现防抖函数 防抖函数的3种经典实现方案的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号