返回

三言两语带你秒懂防抖函数!

前端

防抖函数原理

防抖函数的基本原理是:当一个函数被触发时,它并不立即执行,而是等待一段时间。如果在这段时间内函数又被触发,那么之前的触发将被取消,函数只会在最后一次触发后执行。

基础防抖函数

function debounce(func, wait) {
  let timeout;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(context, args);
    }, wait);
  };
}

这个函数接收两个参数:func是需要防抖的函数,wait是防抖的时间间隔。函数返回一个新的函数,这个函数在被调用时会立即清除之前的超时计时器,然后重新设置一个新的计时器。如果在新的计时器触发之前函数又被调用,那么之前的计时器将被清除,函数将不会执行。只有当新的计时器触发时,函数才会执行。

改进防抖函数

上述基础防抖函数虽然可以实现基本的防抖功能,但它存在一些问题:

  • 每次调用防抖函数都会创建一个新的超时计时器,这可能会导致性能问题。
  • 防抖函数只支持单一的函数调用,如果函数需要多次调用,那么需要多次调用防抖函数。

为了解决这些问题,我们可以对基础防抖函数进行一些改进:

function debounce(func, wait, immediate) {
  let timeout;
  return function() {
    const context = this;
    const args = arguments;
    const callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      timeout = null;
      if (!immediate) {
        func.apply(context, args);
      }
    }, wait);
    if (callNow) {
      func.apply(context, args);
    }
  };
}

这个改进后的防抖函数接收三个参数:func是需要防抖的函数,wait是防抖的时间间隔,immediate是一个布尔值,表示是否立即执行函数。

新的防抖函数使用了一个闭包来保存超时计时器,这样可以避免每次调用防抖函数都创建一个新的计时器。同时,新的防抖函数支持立即执行函数,如果immediate为true,那么函数会在防抖时间间隔内立即执行一次。

最终版防抖函数

最终版防抖函数如下:

function debounce(func, wait, options) {
  let timeout;
  const context = this;
  const args = arguments;
  const callNow = immediate && !timeout;
  const later = () => {
    timeout = null;
    if (!immediate) {
      func.apply(context, args);
    }
  };
  clearTimeout(timeout);
  timeout = setTimeout(later, wait);
  if (callNow) {
    func.apply(context, args);
  }
}

这个最终版防抖函数接收四个参数:func是需要防抖的函数,wait是防抖的时间间隔,immediate是一个布尔值,表示是否立即执行函数,options是一个对象,可以配置额外的选项。

最终版防抖函数更加灵活,它允许用户配置额外的选项,例如是否立即执行函数、是否取消正在进行的计时器等。同时,最终版防抖函数的代码更加简洁,易于理解和使用。