防抖函数的核心是延迟执行并重置计时,适用于搜索建议等场景。具体实现通过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而不是直接调用func()?
使用apply可以确保函数在正确的上下文中执行,并传递正确的参数。apply允许我们指定this的值(即上下文)和参数数组。这在处理事件监听器等场景时非常重要,因为我们需要确保函数在触发事件的元素上下文中执行。如果直接调用func(),this的值可能会指向全局对象(例如window),导致错误。
防抖和节流的区别是什么?
防抖和节流都是为了优化性能,减少函数执行频率的技术,但它们的策略不同。
防抖 (Debounce): 在事件被触发后,延迟一段时间执行,如果在这段时间内事件再次被触发,则重新计时。最终只执行最后一次触发。适用于搜索建议、调整窗口大小等场景。节流 (Throttle): 在一段时间内,只允许函数执行一次。如果在该时间段内事件被多次触发,只有第一次触发会被执行。适用于滚动事件、鼠标移动等场景。
简单来说,防抖是“最后一次有效”,节流是“一段时间内只执行一次”。
防抖函数的常见应用场景有哪些?
搜索建议: 用户在输入框中输入内容时,不需要每次输入都发送请求,而是等待用户停止输入一段时间后,再发送请求获取搜索建议。调整窗口大小: 在调整窗口大小的过程中,不需要每次调整都重新计算布局,而是等待调整完成后,再重新计算布局。按钮点击: 防止用户快速多次点击按钮,导致重复提交表单或执行其他操作。文本编辑器自动保存: 用户编辑文本时,不需要每次修改都保存,而是等待用户停止编辑一段时间后,再自动保存。
以上就是js如何实现防抖函数 防抖函数的3种经典实现方案的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/161860.html
微信扫一扫
支付宝扫一扫