js函数防抖和节流

本文深入探讨了JavaScript中的函数优化技术,包括防抖(debounce)和节流(throttle)的低配版与高配版实现。通过示例代码详细解释了这两种技术的工作原理,帮助开发者理解如何在实际项目中有效地应用它们,以提高性能和用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数防抖

// 防抖函数低配版
  function denounceOld(fn, delay) {
    // 定时器
    let timer = null
    // 将debounce处理结果当作函数返回
    return function () {
      // 保留调用时的this上下文
      let context = this
      // 保留调用时传入的参数
      let args = arguments
      // 每次事件被触发时,都去清除之前的旧定时器
      if (timer) {
        clearTimeout(timer)
      }
      // 设立新定时器
      timer = setTimeout(function () {
        fn.apply(context, args)
      }, delay)
    }
  }

  // 防抖函数高配版
  function denounceNew(func, wait, immediate) {
    //timeout存储定时器的返回值,result要执行函数的结果
    let timeout,result
    let debounced = function () {
      // 将执行的上下文记录
      let context = this
      // 使用args保存event事件
      let args = arguments

      // 每次执行前先把之前的定时器取消
      if (timeout) clearTimeout(timeout)

      // 是否要立即执行
      if (immediate) {
        let callNow = !timeout
        timeout = setTimeout(function () {
          timeout = null
        }, wait)
        if (callNow) result = func.apply(context, args)
      } else {
        timeout = setTimeout(function () {
          // 将需要执行的函数的环境指定为context上下文,同时将事件传入
          func.apply(context, args)
        }, wait)
      }
      return result
    }
    debounced.cancel = function () {
      clearTimeout(timeout)
      timeout = null
    }
    return debounced
  }

函数节流

// 节流函数低配版
  let throttleOld = function (func, wait) {
    // last为上一次回调触发的时间,第一次设置为0
    let last = 0
    return function () {
      // 保留调用时的this上下文
      let context = this
      // 保留调用时传入的参数
      let args = arguments
      // 记录本次触发回调的时间
      let now = Date.now()

      // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值
      if (now - last >= wait) {
        // 如果时间间隔大于我们设定的时间间隔阈值,则执行回调,同时将now的值赋给last
        last = now
        func.apply(context, args)
      }
    }
  }

  // 节流函数高配版
  let throttleNew = function (func, wait, options) {
    let timeout     //timeout存储定时器
    let context     //context存储上下文
    let args        //args存储func的参数
    let result      //result存储func执行的结果
    let previous = 0    //记录上一次执行func的时间,默认0,也就是第一次func一定执行(now-0)大于wait

    if (!options) options = {} // 如果不设置options时,设置为默认options

    // 定时器函数
    let later = function () {
      // 记录这次的函数执行时间
      previous = options.leading === false ? 0 : Date.now()
      timeout = null
      result = func.apply(context, args)
      if (!timeout) context = args = null
    }

    let throttled = function () {
      let now = Date.now() // 当前时间
      // 如果第一次不执行,previous等于当前时间
      if (!previous && options.leading === false) previous = now
      // 时间间隔-(当前时间-上一次执行时间)
      let remaining = wait - (now - previous)
      context = this
      args = arguments

      //如果remaining<0,那么距离上次执行时间超过wait,如果(now-previous)<0,也就是now<previous
      if (remaining <= 0 || remaining > wait) {
        // 清除定时器
        if (timeout) {
          clearTimeout(timeout)
          timeout = null
        }
        previous = now // 记录当前时间
        result = func.apply(context, args) //执行函数func
        if (!timeout) context = args = null
      } else if (!timeout && options.trailing !== false) {
        timeout = setTimeout(later, remaining)
      }
      return result
    }

    throttled.cancel = function () {
      clearTimeout(timeout)
      previous = 0
      timeout = context = args = null
    }

    return throttled
  }

underscore文档
参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值