[面试] 手写题-防抖,节流
防抖:n秒内只执行一次,输入框搜索,窗口resize
事件被触发后,等一段时间(比如300ms)没有再触发时,才执行一次函数。如果在这段时间内又触发了事件,则重新计时。
场景举例
- 输入框搜索:用户输入时不马上请求接口,等停止输入一段时间后才发送请求,避免频繁调用接口。
- 调整窗口大小:窗口尺寸变化频繁,只在调整停止后执行一次重绘。
function debounce(func, delay) {let timer = null;return function(...args) {clearTimeout(timer);timer = setTimeout(() => {func.apply(this, args);}, delay);};
}
解析
- timer 用来保存当前计时器。
- 每次触发函数时,先清除旧的计时器。
- 设置新的计时器,延迟 delay 毫秒后执行目标函数 func。
- apply(this, args) 保持调用时的上下文和参数。
节流 每隔n秒执行一次,滚动
保证在一个固定时间间隔内,函数最多执行一次。即使触发事件很多,函数调用频率也会被限制。
场景举例
滚动加载:监听滚动事件时,不想频繁调用函数,节省性能。
按钮连续点击防止多次提交。
function throttle(func, delay) {let lastTime = 0;return function(...args) {const now = new Date.getTime();if (now - lastTime >= delay) {lastTime = now;func.apply(this, args);}};
}
解析
- lastTime 记录上一次执行函数的时间戳。
- 当前时间 now 减去 lastTime 大于等于间隔时,执行函数,并更新时间戳。
- 其他触发在这段时间内的调用都会被忽略。
参考:
【JS】防抖(debounce)和节流(throttle)
JavaScript 防抖 - Web前端工程师面试题讲解-b站
JavaScript 节流 - Web前端工程师面试题讲解-b站