【js手写题】手写节流和防抖函数
对于前端工程师来说,节流(throttle)和防抖(debounce)是两个非常重要且常见的概念。它们的目的是减少事件触发的频率,提高性能。在面试中,经常会被要求手写节流和防抖的实现代码。本文将详细解释节流和防抖的原理,并提供一种易于理解和记忆的实现方式,帮助你在面试中脱颖而出。
什么是节流和防抖?
节流和防抖都是控制事件触发频率的技术,但两者的应用场景和效果略有不同:
- 节流:指连续触发事件时,只在特定时间间隔内执行一次事件处理函数。类比现实生活中的水龙头,无论你开关水龙头多少次,在一定时间内水龙头只会滴下固定数量的水滴。
- 防抖:指连续触发事件时,只在最后一次触发后的特定时间后才执行事件处理函数。类比现实生活中的电梯,无论你按了多少次按钮,电梯只会在最后一次按下按钮后的固定时间后才会启动。
节流的使用场景
- 滚动事件:在滚动事件中使用节流,可以降低事件触发的频率,提高页面性能。例如:
window.addEventListener('scroll', throttle(handleScroll, 200));
- 按钮点击:对于需要防止用户重复点击提交的按钮,可以使用节流来控制点击频率。例如:
button.addEventListener('click', throttle(handleClick, 500));
- 自动完成(Autocomplete):当用户在搜索框中输入内容时,可以使用节流来控制建议列表的更新频率,避免过于频繁的请求。例如:
input.addEventListener('input', throttle(updateSuggestions, 300));
防抖的使用场景
- 搜索框输入:当用户在搜索框中输入内容时,可以使用防抖来延迟发送请求,直到用户停止输入一段时间后再发送请求,避免过于频繁的请求。例如:
input.addEventListener('input', debounce(sendRequest, 500));
- 窗口大小调整:在窗口大小调整事件中使用防抖,可以避免在调整过程中多次触发事件处理函数,只在调整完成后执行一次。例如:
window.addEventListener('resize', debounce(handleResize, 200));
- 表单验证:对于需要在用户输入内容后进行验证的表单,可以使用防抖来延迟验证的触发,避免过于频繁的验证。例如:
input.addEventListener('input', debounce(validateInput, 300));
节流函数的实现
function throttle(fn, delay) {
let timer = 0;
return function() {
if (timer) return;
timer = setTimeout(() => {
fn.apply(this, arguments); // 延迟执行函数
timer = 0; // 执行完毕后重置计时器标志
}, delay);
}
}
代码解释:
- 定义一个计时器变量
timer
,初始值为 0。 - 返回一个新函数,用于包装原始函数
fn
。 - 在新函数中,首先检查
timer
是否为真值,如果是,则直接返回,不执行函数。 - 如果
timer
为假值,则使用setTimeout
延迟执行原始函数fn
,延迟时间为delay
。 - 使用
apply
方法调用原始函数,传入当前上下文和参数。 - 函数执行完毕后,将
timer
重置为 0,以便下一次事件触发时可以再次执行函数。
防抖函数的实现
function debounce(fn, delay) {
let timer = 0;
return function() {
if (timer) {
clearTimeout(timer); // 清除之前的定时器
}
timer = setTimeout(() => {
fn.apply(this, arguments); // 延迟执行函数
timer = 0; // 执行完毕后重置计时器标志
}, delay);
}
}
代码解释:
- 定义一个计时器变量
timer
,初始值为 0。 - 返回一个新函数,用于包装原始函数
fn
。 - 在新函数中,首先检查
timer
是否为真值,如果是,则使用clearTimeout
清除之前的定时器。 - 使用
setTimeout
设置一个新的定时器,延迟执行原始函数fn
,延迟时间为delay
。 - 使用
apply
方法调用原始函数,传入当前上下文和参数。 - 函数执行完毕后,将
timer
重置为 0,以便下一次事件触发时可以重新设置定时器。
总结
节流和防抖是前端性能优化的重要技术,它们通过控制事件触发的频率来提高页面性能。节流适用于需要连续触发但要限制执行频率的场景,如滚动事件、按钮点击等;防抖适用于连续触发但只需要执行最后一次的场景,如搜索框输入、窗口大小调整等。
通过本文提供的易于理解和记忆的实现方式,你可以在面试中轻松地手写节流和防抖函数,展示你扎实的前端功底和编码能力。同时,深入理解节流和防抖的原理及应用场景,将帮助你在实际开发中优化页面性能,提供更好的用户体验。
转载自:https://juejin.cn/post/7352079364610539539