
防抖Debounce使用点击事件试下反例1return使用剪头函数 console.log(this)中的this会一直是window绑定不上它的调用者dom!DOCTYPE html html langzh-CN body input idsearchInput placeholder输入测试 script function debounce(fn, delay 300) { let timer null; // 返回箭头函数 return (...args) { // return function (...args) { clearTimeout(timer); timer setTimeout(() { console.log(this); fn.apply(this, args); }, delay); } } function handle() { console.log(当前this:, this); } const dbHandle debounce(handle); const input document.querySelector(#searchInput); // 直接把防抖函数交给事件监听 input.addEventListener(input, dbHandle); /script /body /html反例2!DOCTYPE html html langzh-CN body input idsearchInput placeholder输入测试 script function debounce(fn, delay 300) { let timer null; // 返回箭头函数 return function (...args) { clearTimeout(timer); timer setTimeout(() { console.log(this); fn.apply(this, args); }, delay); } } const handle () { console.log(当前this:, this); } // function handle() { // console.log(当前this:, this); // } const dbHandle debounce(handle); const input document.querySelector(#searchInput); // 直接把防抖函数交给事件监听 input.addEventListener(input, dbHandle); /script /body /html用setTimeout模拟setInterval的实现function myInterval(fn, delay) { // 定义递归函数负责执行回调并重新设置定时器 function loop() { fn(); // 执行目标函数 // 再次调用 setTimeout形成循环用闭包保存 timer方便清除 timer setTimeout(loop, delay); } // 启动第一次执行 let timer setTimeout(loop, delay); // 返回清除定时器的方法 return () clearTimeout(timer); }使用示例// 定义要循环执行的函数 function logTime() { console.log(当前时间:, new Date().toLocaleTimeString()); } // 模拟每 1000ms 执行一次类似 setInterval const cancel myInterval(logTime, 1000); // 5秒后停止循环 setTimeout(() { cancel(); console.log(已停止); }, 5000);二、这种方式的好处避免回调函数执行时间导致的间隔偏差原生setInterval会按照固定间隔计划下一次执行但若前一次回调执行时间超过了间隔比如回调耗时 200ms间隔 100ms会导致多次回调堆积、间隔混乱。而setTimeout模拟的方式是在前一次回调执行完毕后才开始计算下一次的间隔确保实际间隔不小于设定值更符合 “执行完再等一段时间” 的预期。更灵活的控制可以在每次循环中动态修改下一次的延迟时间比如根据业务场景调整间隔而setInterval的间隔是固定的。function myInterval(fn, delay) { function loop() { fn(); // 动态调整下一次延迟比如每次增加 100ms delay 100; timer setTimeout(loop, delay); } let timer setTimeout(loop, delay); return () clearTimeout(timer); }避免不可控的回调堆积若页面处于后台等情况setInterval可能会在页面恢复后一次性执行堆积的回调而setTimeout模拟的方式每次只计划下一次执行不会堆积。总结setTimeout模拟setInterval虽然代码稍复杂但在间隔准确性、灵活性和避免回调堆积上更有优势适合对执行时机要求较高的场景。