防抖函数的核心是延迟执行并重置计时,适用于搜索建议等场景。具体实现通过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号