likes
comments
collection
share

【js手写题】手写节流和防抖函数

作者站长头像
站长
· 阅读数 52

对于前端工程师来说,节流(throttle)和防抖(debounce)是两个非常重要且常见的概念。它们的目的是减少事件触发的频率,提高性能。在面试中,经常会被要求手写节流和防抖的实现代码。本文将详细解释节流和防抖的原理,并提供一种易于理解和记忆的实现方式,帮助你在面试中脱颖而出。

什么是节流和防抖?

节流和防抖都是控制事件触发频率的技术,但两者的应用场景和效果略有不同:

  • 节流:指连续触发事件时,只在特定时间间隔内执行一次事件处理函数。类比现实生活中的水龙头,无论你开关水龙头多少次,在一定时间内水龙头只会滴下固定数量的水滴。
  • 防抖:指连续触发事件时,只在最后一次触发后的特定时间后才执行事件处理函数。类比现实生活中的电梯,无论你按了多少次按钮,电梯只会在最后一次按下按钮后的固定时间后才会启动。

节流的使用场景

  1. 滚动事件:在滚动事件中使用节流,可以降低事件触发的频率,提高页面性能。例如:
window.addEventListener('scroll', throttle(handleScroll, 200));
  1. 按钮点击:对于需要防止用户重复点击提交的按钮,可以使用节流来控制点击频率。例如:
button.addEventListener('click', throttle(handleClick, 500));
  1. 自动完成(Autocomplete):当用户在搜索框中输入内容时,可以使用节流来控制建议列表的更新频率,避免过于频繁的请求。例如:
input.addEventListener('input', throttle(updateSuggestions, 300));

防抖的使用场景

  1. 搜索框输入:当用户在搜索框中输入内容时,可以使用防抖来延迟发送请求,直到用户停止输入一段时间后再发送请求,避免过于频繁的请求。例如:
input.addEventListener('input', debounce(sendRequest, 500));
  1. 窗口大小调整:在窗口大小调整事件中使用防抖,可以避免在调整过程中多次触发事件处理函数,只在调整完成后执行一次。例如:
window.addEventListener('resize', debounce(handleResize, 200));
  1. 表单验证:对于需要在用户输入内容后进行验证的表单,可以使用防抖来延迟验证的触发,避免过于频繁的验证。例如:
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);
  }
}

代码解释:

  1. 定义一个计时器变量 timer,初始值为 0。
  2. 返回一个新函数,用于包装原始函数 fn
  3. 在新函数中,首先检查 timer 是否为真值,如果是,则直接返回,不执行函数。
  4. 如果 timer 为假值,则使用 setTimeout 延迟执行原始函数 fn,延迟时间为 delay
  5. 使用 apply 方法调用原始函数,传入当前上下文和参数。
  6. 函数执行完毕后,将 timer 重置为 0,以便下一次事件触发时可以再次执行函数。

防抖函数的实现

function debounce(fn, delay) {
  let timer = 0;
  return function() {
    if (timer) {
      clearTimeout(timer); // 清除之前的定时器
    }
    timer = setTimeout(() => {
      fn.apply(this, arguments); // 延迟执行函数
      timer = 0; // 执行完毕后重置计时器标志
    }, delay);
  }
}

代码解释:

  1. 定义一个计时器变量 timer,初始值为 0。
  2. 返回一个新函数,用于包装原始函数 fn
  3. 在新函数中,首先检查 timer 是否为真值,如果是,则使用 clearTimeout 清除之前的定时器。
  4. 使用 setTimeout 设置一个新的定时器,延迟执行原始函数 fn,延迟时间为 delay
  5. 使用 apply 方法调用原始函数,传入当前上下文和参数。
  6. 函数执行完毕后,将 timer 重置为 0,以便下一次事件触发时可以重新设置定时器。

总结

节流和防抖是前端性能优化的重要技术,它们通过控制事件触发的频率来提高页面性能。节流适用于需要连续触发但要限制执行频率的场景,如滚动事件、按钮点击等;防抖适用于连续触发但只需要执行最后一次的场景,如搜索框输入、窗口大小调整等。

通过本文提供的易于理解和记忆的实现方式,你可以在面试中轻松地手写节流和防抖函数,展示你扎实的前端功底和编码能力。同时,深入理解节流和防抖的原理及应用场景,将帮助你在实际开发中优化页面性能,提供更好的用户体验。

转载自:https://juejin.cn/post/7352079364610539539
评论
请登录